Commit Graph

115 Commits

Author SHA1 Message Date
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
Pierre-Yves David
92bf4dcbdc transaction: pass the transaction to 'pending' callback
The callback will likely need to perform some operation related to the
transaction (eg: backing files up). So we better pass the current transaction as
the callback argument. Otherwise callback that needs it has to rely on horrible
weak reference trick.

The first foreseen user of this is changelog._writepending. We would like it to
register the temporary file it create for cleanup purpose.
2014-11-08 16:27:50 +00:00
Pierre-Yves David
6ab03ec965 transaction: gather backupjournal logic together in the __init__
The initialisation of file-backup related variable were a bit scattered, we
gather them together.
2014-11-05 10:22:17 +00:00
Pierre-Yves David
b91f1df8cd transaction: handle missing file in backupentries (instead of using entries)
The case where a backup of a missing file was requested was previously
handled by the 'entries' list. As the 'backupentries' is about to gain
ability to backup files outside of '.hg/store', we want it to be able
to handle the missing file too.

Reminder: using 'addbackup' on a missing file means that such file needs to be
deleted if we rollback the transaction.
2014-11-05 01:38:48 +00:00
Pierre-Yves David
1d1e3a5b9c transaction: factorise append-only file registration
The addition is done in two different places but differs slightly. We factorise
this addition to ensure it is consistent in all places.
2014-11-05 10:13:01 +00:00
Pierre-Yves David
b9cd014175 transaction: document tr.add 2014-11-05 13:00:48 +00:00
Pierre-Yves David
9a1f491fee transaction: drop backupentries logic from startgroup and endgroup
The `startgroup` and `endgroup` methods are used in a very specific
context to wrap a very specific operation (revlog truncation). It does
not make sense to perform any other operations during such a "group"
(eg:file backup). There is currently no user of backupfile during a
"group" so we drop the group-specific code and restrict authorized
operations during "group".
2014-11-05 10:05:38 +00:00
Pierre-Yves David
483eb136e7 transaction: document startgroup and endgroup
These enigmatic methods are only used in repair. We document them to clarify
there purpose and user.
2014-11-05 10:00:15 +00:00
Pierre-Yves David
36a4f98617 transaction: mark backup-related attributes private
As the transaction is gaining more functions and attributes, it is important to clarify
what is part of the public API.
2014-11-05 09:31:57 +00:00
Pierre-Yves David
63c82fbc8a transaction: document the contents of tr.backupentries
Now that all items are known we can document it.
2014-11-05 01:30:29 +00:00
Pierre-Yves David
9d5b590e75 transaction: drop the third item in tr.backupentries
This third item is always None and never used.
2014-11-05 01:33:16 +00:00
Pierre-Yves David
bff90c5de3 transaction: allow registering a post-close callback
The addchangegroup code considers the transaction done after a 'tr.close()' call
and schedules the hook's execution for after lock release. In the nested transaction
case, the transaction is not yet committed and we must delay this scheduling.
We add an 'addpostclose' method (like the 'addpending' and 'addfinalize' ones) that
registers code to be run if the transaction is successfully committed.
2014-10-28 14:24:43 +01:00
Pierre-Yves David
7ae09eecbb transaction: allow registering a finalization callback
The new 'addfinalize' method allows people to register a callback to
be triggered when the transaction is closed. This aims to get rid of
explicit calls to 'changelog.finalize'. This also obsoletes the
'onclose' function but removing it is not in the scope of this series.
2014-10-17 22:28:09 -07:00
Pierre-Yves David
16a2a58b80 transaction: add 'writepending' logic
The contents of the transaction must be flushed to disk before running
a hook. But it must be flushed to a special file so that the normal
reader does not use it. This logic is currently in the changelog only.
We add some facility to register such operations in the transaction
itself.
2014-10-17 21:19:54 -07:00
Pierre-Yves David
34fb3a3cdd transaction: only generate file when we actually close the transaction
Before this change, the file were written for every call to `tr.close()`
exposing data to reader far too early.
2014-10-17 21:25:48 -07:00
Pierre-Yves David
245e001eb5 transaction: extract file generation into its own function
We extract the code generating files into its own function. We are
about to move this code around to fix a bug. We'll need it in a
function soon to reuse it for "pending" logic. So we move the code
into a function instead of moving it twice.
2014-09-29 00:59:25 -07:00
Durham Goode
fd796ba36d transactions: change backupfiles format to use newlines
Previously the journal.backupfiles file was delimited by \0. Now we delimit it
using \n (same as the journal file). This allows us to change the number of
values in each line more easily, rather than relying on the count of \0's.
2014-10-21 12:38:28 -07:00
Durham Goode
646f35dbec transactions: add version number to journal.backupfiles
The transaction format will be changing a bit over the next releases, so let's
go ahead and add a version number to make backwards compatibility easier. This
whole file format was broken prior to 3.2 (see previous patch), so changing it
now is pretty low risk.
2014-10-21 11:37:29 -07:00
Durham Goode
faf9d65282 transactions: fix hg recover with fncache backups
The transaction backupfiles logic was broken for 'hg recover'.  The file format
is XXX\0XXX\0YYY\0YYY\0 but the parser did a couple things wrong. 1) It went one
step beyond the final \0 and tried to read past the end of the array. 2)
array[i:i+1] returns a single item, instead of two items as intended.

Added a test to catch it, which turns out to be the first actual 'hg recover'
test.
2014-10-20 16:53:56 -07:00