Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrTransactionProcessingStopped = errors.New("transaction processing stopped")
ErrTransactionProcessingStopped is returned when the TransactionManager stops processing transactions.
Functions ¶
func OpenDatabase ¶
OpenDatabase opens a new database handle to a database at the given path.
Types ¶
type InvalidReferenceFormatError ¶
type InvalidReferenceFormatError struct { // ReferenceName is the reference with invalid format. ReferenceName git.ReferenceName }
InvalidReferenceFormatError is returned when a reference name was invalid.
func (InvalidReferenceFormatError) Error ¶
func (err InvalidReferenceFormatError) Error() string
Error returns the formatted error string.
type LogIndex ¶
type LogIndex uint64
LogIndex points to a specific position in a repository's write-ahead log.
type ReferenceUpdate ¶
type ReferenceUpdate struct { // OldOID is the old OID the reference is expected to point to prior to updating it. // If the reference does not point to the old value, the reference verification fails. OldOID git.ObjectID // NewOID is the new desired OID to point the reference to. NewOID git.ObjectID }
ReferenceUpdate describes the state of a reference's old and new tip in an update.
type ReferenceUpdates ¶
type ReferenceUpdates map[git.ReferenceName]ReferenceUpdate
ReferenceUpdates contains references to update. Reference name is used as the key and the value is the expected old tip and the desired new tip.
type ReferenceVerificationError ¶
type ReferenceVerificationError struct { // ReferenceName is the name of the reference that failed verification. ReferenceName git.ReferenceName // ExpectedOID is the OID the reference was expected to point to. ExpectedOID git.ObjectID // ActualOID is the OID the reference actually pointed to. ActualOID git.ObjectID }
ReferenceVerificationError is returned when a reference's old OID did not match the expected.
func (ReferenceVerificationError) Error ¶
func (err ReferenceVerificationError) Error() string
Error returns the formatted error string.
type Transaction ¶
type Transaction struct { // SkipVerificationFailures causes references updates that failed the verification step to be // dropped from the transaction. By default, any verification failures abort the entire transaction. // // The default behavior maps to the `--atomic` flag of `git push`. When this is set, the behavior matches // what happens git's behavior without the flag. SkipVerificationFailures bool // ReferenceUpdates contains the reference updates to be performed. ReferenceUpdates }
Transaction is a unit-of-work that contains reference changes to perform on the repository.
type TransactionManager ¶
type TransactionManager struct {
// contains filtered or unexported fields
}
TransactionManager is responsible for transaction management of a single repository. Each repository has a single TransactionManager; it is the repository's single-writer. It accepts writes one at a time from the admissionQueue. Each admitted write is processed in three steps:
- The references being updated are verified by ensuring the expected old tips match what the references actually point to prior to update. The entire transaction is by default aborted if a single reference fails the verification step. The reference verification behavior can be controlled on a per-transaction level by setting: - The reference verification failures can be ignored instead of aborting the entire transaction. If done, the references that failed verification are dropped from the transaction but the updates that passed verification are still performed. - The reference verification may also be skipped if the write is force updating references. If done, the current state of the references is ignored and they are directly updated to point to the new tips.
- The transaction is appended to the write-ahead log. Once the write has been logged, it is effectively committed and will be applied to the repository even after restarting.
- The transaction is applied from the write-ahead log to the repository by actually performing the reference changes.
The goroutine that issued the transaction is waiting for the result while these steps are being performed. As there is no transaction control for readers yet, the issuer is only notified of a successful write after the write has been applied to the repository.
TransactionManager recovers transactions after interruptions by applying the write-ahead logged transactions to the repository on start up.
TransactionManager maintains the write-ahead log in a key-value store. It maintains the following key spaces: - `repository/<repository_id:string>/log/index/applied`
- This key stores the index of the log entry that has been applied to the repository. This allows for determining how far a repository is in processing the log and which log entries need to be applied after starting up. Repository starts from log index 0 if there are no log entries recorded to have been applied.
- `repository/<repository_id:string>/log/entry/<log_index:uint64>`
- These keys hold the actual write-ahead log entries. A repository's first log entry starts at index 1 and the log index keeps monotonically increasing from there on without gaps. The write-ahead log entries are processed in ascending order.
The values in the database are marshaled protocol buffer messages. Numbers in the keys are encoded as big endian to preserve the sort order of the numbers also in lexicographical order.
func NewTransactionManager ¶
func NewTransactionManager(db *badger.DB, repository *localrepo.Repo) *TransactionManager
NewTransactionManager returns a new TransactionManager for the given repository.
func (*TransactionManager) Propose ¶
func (mgr *TransactionManager) Propose(ctx context.Context, transaction Transaction) error
Propose queues a transaction for the TransactionManager to process. Propose returns once the transaction has been successfully applied to the repository.
Transaction is not committed if any of the following errors is returned: - InvalidReferenceFormatError is returned when attempting to update a reference with an invalid name. - ReferenceVerificationError is returned when the reference does not point to the expected old tip.
Transaction may or may not be committed if any of the following errors is returned:
- ErrTransactionProcessing stopped is returned when the TransactionManager is closing and stops processing transactions.
- Unexpected error occurs.
func (*TransactionManager) Run ¶
func (mgr *TransactionManager) Run() error
Run starts the transaction processing. On start up Run loads the indexes of the last appended and applied log entries from the database. It will then apply any transactions that have been logged but not applied to the repository. Once the recovery is completed, Run starts processing new transactions by verifying the references, logging the transaction and finally applying it to the repository. The transactions are acknowledged once they've been applied to the repository.
Run keeps running until Stop is called or it encounters a fatal error. All active Propose calls return ErrTransactionProcessingStopped when Run returns.
func (*TransactionManager) Stop ¶
func (mgr *TransactionManager) Stop()
Stop stops the transaction processing causing Run to return.