Automatically repair torn writes on opening#155
Conversation
|
Torn writes always coincide with a still locked writer. This can currently only be unlocked with an explicit |
src/Storage/WritableStorage.js
Outdated
| if (!this.lock()) { | ||
| return true; | ||
| } | ||
| this.checkTornWrites(); |
There was a problem hiding this comment.
Doing this here is a waste, because in most cases there was no previously failed write.
This check should only happen when a lock still exists, but is reclaimed. That in turn can only happen when:
- the user explicitly forces the reclaiming (e.g. by a constructor option)
- the previous lock has "timed out"
Regarding timing out the lock, a possible way to do this sensibly is this (see proper-lockfile):
- touch the lock file every X timeframe (to update mtime)
- when opening, check if the lock is at least 2*X "old" and if so, reclaim it
Only checking if the lock is X time old without touching it would cause trouble with long running applications. Touching the lock every X time is additional work. So if implemented this way, this auto-reclaiming needs to be optional.
For the manual reclaiming, the API needs to be reconsidered:
try {
eventstore = new EventStore(...);
} catch (EventStoreLockedError e) {
eventstore = new EventStore(..., { forceLock: true });
}wrapping class instanciation in a try/catch is awkward at best and if the reclaiming is known to be safe at instanciation time this can always be reduced to eventstore = new EventStore(..., { forceLock: true }); anyway.
eventstore = new EventStore(..., { lock: EventStore.LOCK_AUTO, lockTimeout: 60 }); // Use lock dir with timeout (60s), reclaim+repair if timed out
eventstore = new EventStore(..., { lock: EventStore.LOCK_FORCE }); // Always take the lock, reclaim+repair if lock exists
eventstore = new EventStore(..., { lock: EventStore.LOCK_MANUAL }); // Throw if an second instance is created, needs manual intervention (delete lock) after a crash
Right now the behaviour is LOCK_MANUAL. What would be a good default once the other methods are implemented? Depends on the use-case - LOCK_FORCE is the least safe, LOCK_MANUAL is safest but hard to fix on error and LOCK_AUTO is the dont-make-me-think mode
This change checks the storage for torn writes when force unlocking and truncates all partitions (and indexes) to the last valid write. After a crash, this can be done by doing the following (once):
Related to #31 and #107