Commit Graph

133 Commits

Author SHA1 Message Date
Gregory Szorc
2a792d7c94 transaction: clear callback instances after usage
Prevents double usage and helps reduce reference cycles, which
were observed to occur in `hg convert` and other scenarios where
there are multiple transactions per process.
2016-04-16 09:02:37 -07:00
Durham Goode
67594c134c transaction: allow running file generators after finalizers
Previously, transaction.close would run the file generators before running the
finalizers (see the list below for what is in each). Since file generators
contain the bookmarks and the dirstate, this meant we made the dirstate and
bookmarks visible to external readers before we actually wrote the commits into
the changelog, which could result in missing bookmarks and missing working copy
parents (especially on servers with high commit throughput, since pulls might
fail to see certain bookmarks in this situation).

By moving the changelog writing to be before the bookmark/dirstate writing, we
ensure the commits are present before they are referenced.

This implementation allows certain file generators to be after the finalizers.
We didn't want to move all of the generators, since it's important that things
like phases actually run before the finalizers (otherwise you could expose
commits as public when they really shouldn't be).

For reference, file generators currently consist of: bookmarks, dirstate, and
phases. Finalizers currently consist of: changelog, revbranchcache, and fncache.
2016-04-07 14:10:49 -07:00
Durham Goode
64267e6e4d transaction: abort transaction during hook exception
The new transaction context did not handle the case where an exception during
close should still call release. This cause pretxnclose hooks that failed to
cause the transaction to fail without aborting, thus requiring a hg recover.

I've added a test.
2016-01-19 15:18:21 -08:00
Bryan O'Sullivan
31c9d97ad8 transaction: turn a transaction into a Python context manager
This lets us greatly simply acquire/release cycles.

If the block completes without raising an exception, the transaction
is closed.

Code pattern before:

  try:
    tr = repo.transaction('x')
    # zillions of lines of code
    tr.close()
  finally:
    tr.release()

And after:

  with tr.transaction('x'):
    # ...
2016-01-15 13:14:47 -08:00
Martin von Zweigbergk
6a744a4d74 transaction: remove 'if True:'
This seems to be left over from 5ae82d2dc4c0 (transaction: reorder
unlinking .hg/journal and .hg/journal.backupfiles, 2015-10-16).
2016-01-06 11:12:09 -08:00
Matt Mackall
cf710e0ab1 spelling: fix typo in transaction error messages 2015-10-17 15:28:02 -05:00
FUJIWARA Katsunori
56c4c4cb1b transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
After this reordering, absence of '.hg/journal' just before starting
new transaction means also absence of '.hg/journal.backupfiles'.

In this case, all temporary files for preceding transaction should be
completely unlinked, and HG_PENDING doesn't cause unintentional
reading stalled temporary files in.

Otherwise, 'repo.transaction()' raises exception with "run 'hg
recover' to clean up transaction" hint.
2015-10-16 03:29:51 +09:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
FUJIWARA Katsunori
47524f74ef transaction: add releasefn to notify the end of a transaction scope
'releasefn' is used by subsequent patch, to do appropriate action
according to the result of it at the end of a transaction scope.

To ensure that 'releasefn' is invoked only once, this patch invokes it
after assignment 'self.journal = None', because such assignment
prevents from invoked 'transaction._abort()' again via '__del__()'.

    def __del__(self):
        if self.journal:
            self._abort()
2015-10-09 03:53:46 +09:00
Gregory Szorc
04a726f0c8 transaction: use absolute_import 2015-08-08 20:10:23 -07:00
Gregory Szorc
5380dea2a7 global: mass rewrite to use modern exception syntax
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".

This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.

This patch was produced by running `2to3 -f except -w -n .`.
2015-06-23 22:20:08 -07:00
Gregory Szorc
3aa1c73868 global: mass rewrite to use modern octal syntax
Python 2.6 introduced a new octal syntax: "0oXXX", replacing "0XXX". The
old syntax is not recognized in Python 3 and will result in a parse
error.

Mass rewrite all instances of the old octal syntax to the new syntax.

This patch was generated by `2to3 -f numliterals -w -n .` and the diff
was selectively recorded to exclude changes to "<N>l" syntax conversion,
which will be handled separately.
2015-06-23 22:30:33 -07:00
Matt Mackall
1a860a7827 merge with stable 2015-05-27 17:41:42 -05:00
Pierre-Yves David
e78e0b6b0c transaction: really fix _addbackupentry key usage (issue4684)
The fix in a795188178a1 is actually wrong. We now use the filename to match what
'_addentry'. This whole untested code is quite suspicious. This seems to point
that no one is ever running 'tr.find' for a backup file.
2015-05-26 13:02:28 -07:00
Pierre-Yves David
1dde6a5eaf transaction: use the proper variable in '_addbackupentry' (issue4684)
The 'file' variable was undefined but resolved to the 'file' built-in.
This is why pylint complains about overwriting built-ins...
2015-05-22 12:13:18 -05:00
Matt Mackall
51fd20a56a merge with stable 2015-05-23 15:55:04 -05:00
Michael O'Connor
d4eb35d7ec transaction: add missing newline to message
Add a missing newline to the "journal was created by a
different version of Mercurial" message.
2015-04-14 10:59:26 -04:00
Pierre-Yves David
7e5ddaf348 recover: catch any exception, not just Exception
We want recover to be rock solid.
2015-05-18 15:38:24 -05:00
Pierre-Yves David
4c1ee6d2d1 transaction: add a validation stage
The 'transaction' object can now be fed a 'validator' function. This function
will be run right before the transaction is closed to validate its content. The
target usage is hooks. The validation function is expected to raise an exception
when it wants to abort the transaction.

This only introduce the idea with a default no-op validator. Actual usage is in
the next changeset.
2015-03-09 22:43:36 -07:00
Pierre-Yves David
be1b3a5e03 transaction: include backup file in the "undo" transaction
Once the transaction is closed, we now write transaction related data for
possible future undo. For now, we only do it for full file "backup" because
their were not handle at all in that case. In the future, we could move all the
current logic to set undo up (that currently exists in localrepository) inside
transaction itself, but it is not strictly requires to solve the current
situation.
2015-01-16 18:34:14 -08:00
Pierre-Yves David
8984d47c1b transaction: pass the name of the "undo" journal to the transaction
It is time for the transaction to be responsible for setting up the
undo data. It is necessary to move this logic into the transaction
because many more files are handled now, and the transaction is the
object tracking them all.

The value can be set to None if no undo should be set.
2015-01-16 19:35:04 -08:00
Pierre-Yves David
03d5cdc6b3 transaction: clarify the name of 'journal' argument for transaction
The argument is a string containing the journal name (used as prefix for all
other transaction file). This is not the transaction file itself. So we clarify
this.
2015-01-16 14:54:24 -08:00
Pierre-Yves David
09bcff37bf transaction: use 'util.copyfile' for creating backup
Using 'copyfile' (single file) instead of 'copyfiles' (tree) will ensures
destination file will be overwritten. This will prevent some abort if backup
file are left in place for random reason.

It also seems more correct.
2015-01-05 12:44:15 -08:00
Gregory Szorc
433ea5a1b2 transaction: support for callbacks during abort
Previous transaction work added callbacks to be called during regular
transaction commit/close. As part of refactoring Mozilla's pushlog
extension (an extension that opens a SQLite database and tries to tie
its transaction semantics to Mercurial's transaction), I discovered that
the new transaction APIs were insufficient to avoid monkeypatching
transaction instance internals. Adding a callback that is called during
transaction abort removes the necessity for monkeypatching and completes
the API.
2015-01-06 21:56:33 -08:00
Pierre-Yves David
c56675c8d2 transaction: use the right location when cleaning up backup file (issue4479)
The location variable fetch from the loop and the one used to actually fetch it
mismatched. We fix the name to ensure file outside of store are cleaned up.
2015-01-05 15:00:02 -08:00
Pierre-Yves David
8985258968 vfs: add a 'split' method
This method has the same behavior as the 'os.path.split' function, but having
it in vfs will allow handling of tricky encoding situations in the future.

In the same patch, we replace the use of 'os.path.split' in the transaction code.
2014-12-15 13:32:34 -08:00
Pierre-Yves David
329429e77c vfs: add a 'reljoin' function for joining relative paths
The vfs.join method only works for absolute paths. We need something
that works for relative paths too when transforming filenames. Since
os.path.join may misbehave in tricky encoding situations, encapsulate
the new join method in our vfs abstraction. The default implementation
remains os.path.join, but this opens the door to other VFSes doing
something more intelligent based on their needs.

In the same go, we replace the usage of 'os.path.join' in transaction code.
2014-12-15 13:27:46 -08:00
Mads Kiilerich
b420dd92b1 spelling: fixes from proofreading of spell checker issues 2014-04-17 22:47:38 +02:00
Pierre-Yves David
511030e86e transaction: remove the 'onabort' mechanism
It has no known users. If someones needs similar functionality, a new 'addabort'
method similar to 'addfinalize' should be added.
2014-12-04 13:52:46 -08:00
Pierre-Yves David
61ff2e647d transaction: remove the redundant 'onclose' mechanism
It is superseded by the 'addfinalize' function and all its user have been
migrated.
2014-12-04 13:51:41 -08:00
Pierre-Yves David
3ace7493d7 transaction: write pending generated files
Such file are generated with a .pending prefix. It is up to the reader to
implement the necessary logic for reading pending files.

We add a test to ensure pending files are properly cleaned-up in both success and
error cases.
2014-10-17 22:19:05 -07:00
Pierre-Yves David
58e32f1eeb transaction: have _generatefile return a boolean
The function returns True if any files were generated. This will be
used to know if any pending files have been written.
2014-10-17 21:57:32 -07:00
Pierre-Yves David
81a1fe4d5b transaction: allow generating files with a suffix
This will allow us to generate temporary pending files. Files
generated with a suffix are assumed temporary and will be cleaned up
at the end of the transaction.
2014-09-29 01:29:08 -07:00
Matt Mackall
3f845e51cb transaction: fix some docstring grammar 2014-11-19 09:52:05 -06:00
Pierre-Yves David
ecac877d99 transaction: accept a 'location' argument for registertmp
This will allow generation of temporary files outside of store. This will be
useful for bookmarks.
2014-11-12 14:57:41 +00:00
Pierre-Yves David
46df0be40b transaction: drop special handling for phases and bookmarks generation
We are still doing double backups, but now that we have proper
location handling this is less of an issue. Dropping this simplifies
the code before we add some pending-related logic.

This also ensures we actually test the new 'location' mechanism.
2014-11-12 14:47:48 +00:00
Pierre-Yves David
b9594d1c53 transaction: use 'location' instead of 'vfs' objects for file generation
The argument is now a location name. The location must be present in the
'vfsmap' provided to the transaction at creation time.
2014-10-17 20:53:42 -07:00
Pierre-Yves David
c1cac6ba41 transaction: use 'location' instead of 'vfs' in the addbackup method
This unlock the backup of file outside of store (eg: bookmarks).
2014-11-05 01:59:32 +00:00
Pierre-Yves David
414fa72b29 addbackup: handle file in subdirectory
The current naming scheme ('journal.backups.<file>') resulted is bad directory
name when 'file' was in a subdirectory. We now extract the directory name and
create the backupfile within it.

We plan to use file in a subdirectory for cachefile.
2014-11-14 00:14:23 +00:00
Pierre-Yves David
70e9add6df addbackup: use the vfs for the backup destination too
The backup file location was always computed using the opener, bypassing the
'location' setting. (And making the feature broken.)
2014-11-14 14:54:55 +00:00
Pierre-Yves David
cec71977a9 transaction: set backupentries version to proper value
Now that all mechanisms are in place, we can advertise it with a
proper new version.
2014-11-13 11:17:36 +00:00
Pierre-Yves David
4c03465397 transaction: support cache file in backupentries
We do not want to abort if anything wrong happen while handling a cache file.
Cache file have way to be invalidated and if old/bad version stay no
misbehavior will happen. Proper value will eventually be computed and the wrong
will be righten.

This changeset use the transaction reporter (usually writing on stderr) to write
details about failed cache handling. This will only apply to write operation
using a transaction. The usual update during read only operation will stay a
debug message.

I was on the way to bring these message back to debug level when I realised it
could be a feature. People with write access to the repository are likely to
have the power to fix error related to cache (and it is valuable to fix them).
So let the things as is for now.
2014-11-13 11:17:09 +00:00
Pierre-Yves David
382c5bbb8d transaction: use the location value when doing backup
We finally use the 'location' value coupled with the 'vfsmap' to restore backup
for the right file.
2014-10-17 21:04:35 -07:00
Pierre-Yves David
53a1a60278 transaction: pass a vfs map to the transaction
The goal is to allow access to file outside ofthe store directory from the
transaction. The obvious target are the `bookmarks` file. But we can envision
usage for cache too.

We keep passing a main opener explicitly because a lot of code rely on this
default opener. The main opener (operating on store) is using an empty key ''.
2014-10-17 20:49:39 -07:00
Pierre-Yves David
d772e961ee transaction: change the on disk format for backupentries
We need to store new data to improve the current transaction logic:

- location: We want to generate and backup file outside of the 'store' (eg:
  bookmarks, or various cache files). This requires knowing and preserving where
  each file is located. The value of this new field is a string. It will be used
  as a key for a vfs mapping.

- cache: We would like to handle cache file in the transaction code. This
  Will help to have cache consistent with the repository state and avoid
  performance issue on big repository like Mozilla. However, failure to handle
  cache file should not result in a transaction failure. We add a new field that
  carry this information. The value is boolean, A True value mean any error
  while handling this file can be ignored.

Those two mechanisms are not implemented yet, but they are now persisted in the
on disk file. Support for new mechanisms is coming in later changeset.

We update the file format now and will introduce the new features in later
changeset. The format version is set to 0 until we actually support the new feature.
This will prevent misunderstanding between incomplete and final client.

Support for reading both version 1 and (future) version 2 could be achieved
(using default value when reading version 1) but has not been seen as necessary
for now.
2014-11-05 01:52:46 +00:00
Pierre-Yves David
84cb2b6041 transaction: allow registering a temporary transaction file
During the transaction, files may be created to store or expose data
involved in the transaction (eg: changelog index data are written in
a 'changelog.i.a' for hooks). But we do not have an official way to
record such file creation and make sure they are cleaned up. The lack
of clean-up is currently okay because there is a single file involved
and a single producer/consumer.

However, as we want to expose more data (bookmarks, phases, obsmarker)
we need something more solid. The 'backupentries' mechanism could
handle that. Temporary files can be encoded as a backup of nothing
'('', <temporarypath>)'. We "need" to attach it to the same mechanism
as we use to be able to use temporary transaction files outside of
.'store/' and 'backupentries' is expected to gain such feature.

This changeset makes it clear that we should rename 'backupentries' to
something more generic.
2014-11-05 09:27:08 +00:00
Pierre-Yves David
82498ec61b transaction: always generate file on close
The conditionnal was buggy and file were only generated if "onclose" was
defined. By luck, "onclose" was always defined.
2014-11-13 10:22:47 +00:00
Pierre-Yves David
a818f5fbca transaction: extract backupentry registration in a dedicated function
We are about to use the 'backupentry' mechanism to allow cleaning up
transaction-related temporary files (such as 'changelog.i.a'). We start
by extracting the entry registration into its own method for easy reuse.

At that point, I would like to rename the backup-file related variable to
something generic but I'm a bit short of ideas.
2014-11-05 13:06:24 +00:00
Pierre-Yves David
8259127ccb transaction: pass the transaction to 'postclose' callback
This mirrors the API for 'pending' and 'finalize' callbacks. I do not have
immediate usage planned for it, but I'm sure some callback will be happy to
access transaction related data.
2014-11-08 16:35:15 +00:00
Pierre-Yves David
29f854f61a transaction: pass the transaction to 'finalize' callback
The callback will likely need to perform some operation related to the
transaction (eg: registering file update). So we better pass the current
transaction as the callback argument. Otherwise callback that needs it has to
rely on horrible weak reference trick.

This allow already allow us to slay a wild weak reference usage.
2014-11-08 16:31:38 +00:00