/// <summary> /// Constructor for new vending machine. Inventory is automatically stocked when creating the machine. /// </summary> public VendingMachine(IInventorySource inventorySource, ITransactionLogger transactionLogger) { this.inventorySource = inventorySource; this.transactionLogger = transactionLogger; inventory = inventorySource.GetInventory(); }
/// <summary> /// Begin transaction and open the ObjectServer in the specified path/filename /// </summary> /// <param name="serverFilename"></param> /// <param name="serverProfile"></param> /// <returns></returns> public static ObjectServerWithTransaction BeginOpenServer(string serverFilename, Preferences preferences) { ObjectServerWithTransaction r = RollbackAll(serverFilename, preferences, false); if (r != null) { if (r.Transaction == null) { string serverRootPath = Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } TransactionRoot root = TransactionRoot.BeginRoot(serverRootPath); root.Server = r; r.Transaction = root; root.Begin(true); } } else { string serverRootPath = Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } TransactionRoot root = TransactionRoot.BeginRoot(serverRootPath); root.IsDisposing = true; r = new Sop.ObjectServerWithTransaction(serverFilename, root, preferences); ITransactionLogger trans = root.Begin(true); trans.IsDisposing = true; } return(r); }
/// <summary> /// Commit current and Begin a new Transaction keeping Store locks /// upheld in the process. /// </summary> /// <returns></returns> public virtual ITransaction Cycle(bool commit = true) { if (Children != null && Children.Count > 0) { var childrenCopy = new ITransactionLogger[Children.Count]; Children.CopyTo(childrenCopy, 0); ITransaction transReturn = null; foreach (ITransactionLogger trans in childrenCopy) { var t2 = trans.Cycle(commit); if (transReturn == null) { transReturn = t2; } } // just return 1st created Tranasaction, 'always the only one anyway. // Transaction structure has been needing refactor... 'but it works so will do for now... return(transReturn); } LockStores(); if (commit) { Commit(); } else { Rollback(); } var t = Begin(); UnlockStores(); return(t); }
/// <summary> /// Rollback changes to Containers/members of this Transaction /// </summary> public override void Rollback() { base.Rollback(); if (OwnsRoot) { Parent.Rollback(); Parent = null; } }
/// <summary> /// Rollback starting with Children-most transaction(s) then parent /// trans to this trans and its Parent until Root is finally rolled back. /// </summary> public virtual void Rollback() { if (Children != null) { var childrenCopy = new ITransactionLogger[Children.Count]; Children.CopyTo(childrenCopy, 0); foreach (ITransactionLogger trans in childrenCopy) { trans.InternalRollback(IsDisposing); } } // all Transaction classes implement ITransactionLogger so this cast should be OK.. this.InternalRollback(IsDisposing); }
/// <summary> /// Backup the target blocks on disk. /// </summary> /// <param name="readPool"></param> /// <param name="writePool"></param> /// <param name="parent"></param> /// <param name="source"></param> /// <param name="dataChunks"></param> public void Backup(ConcurrentIOPoolManager readPool, ConcurrentIOPoolManager writePool, Algorithm.Collection.ICollectionOnDisk parent, byte[] source, List <DataChunk> dataChunks) { ITransactionLogger trans = parent.Transaction; if (trans != null) { Sop.Transaction.Transaction.LogTracer.Verbose("BulkWriter.Backup: Start for Thread {0}.", Thread.CurrentThread.ManagedThreadId); foreach (var chunk in dataChunks) { Sop.Transaction.Transaction.LogTracer.Verbose("BulkWriter.Backup: inside foreach chunk {0} Thread {1}.", chunk.TargetDataAddress, Thread.CurrentThread.ManagedThreadId); // Identify regions that were not backed up and overwritten yet then back them up... ((TransactionBase)trans).RegisterSave((CollectionOnDisk)parent, chunk.TargetDataAddress, chunk.Size, readPool, writePool); } } }
/// <summary> /// Commit starting Children transaction(s) /// </summary> /// <param name="phase"></param> virtual public bool Commit(CommitPhase phase) { Flush(); if (Children != null && Children.Count > 0) { var childrenCopy = new ITransactionLogger[Children.Count]; Children.CopyTo(childrenCopy, 0); foreach (ITransactionLogger trans in childrenCopy) { if (!trans.InternalCommit(phase)) { return(false); } } } // all Transaction classes implement ITransactionLogger so this cast should be OK.. return(this.InternalCommit(phase)); }
public SystemService( StripeForRBT stripeService, Mailer mailer, ITransactionLogger transactionLogger ) { if (stripeService == null) { throw new ArgumentNullException(nameof(stripeService)); } if (mailer == null) { throw new ArgumentNullException(nameof(mailer)); } StripeService = stripeService; Mailer = mailer; TransactionLogger = transactionLogger; }
public EfCoreCourseService( IHttpContextAccessor httpContextAccessor, ILogger <EfCoreCourseService> logger, IEmailClient emailClient, IImagePersister imagePersister, IPaymentGateway paymentGateway, MyCourseDbContext dbContext, LinkGenerator linkGenerator, ITransactionLogger transactionLogger, IOptionsMonitor <CoursesOptions> coursesOptions) { this.httpContextAccessor = httpContextAccessor; this.imagePersister = imagePersister; this.paymentGateway = paymentGateway; this.coursesOptions = coursesOptions; this.logger = logger; this.dbContext = dbContext; this.linkGenerator = linkGenerator; this.transactionLogger = transactionLogger; this.emailClient = emailClient; }
public AdoNetCourseService( ILogger <AdoNetCourseService> logger, IDatabaseAccessor db, IImagePersister imagePersister, IHttpContextAccessor httpContextAccessor, IEmailClient emailClient, IOptionsMonitor <CoursesOptions> coursesOptions, IPaymentGateway paymentGateway, LinkGenerator linkGenerator, ITransactionLogger transactionLogger) { this.imagePersister = imagePersister; this.coursesOptions = coursesOptions; this.logger = logger; this.emailClient = emailClient; this.httpContextAccessor = httpContextAccessor; this.db = db; this.paymentGateway = paymentGateway; this.linkGenerator = linkGenerator; this.transactionLogger = transactionLogger; }
/// <summary> /// Rollback uncomitted transactions. /// NOTE: this should be invoked upon restart so uncommited transaction(s) /// when program quits in previous run can be rolled back. /// </summary> /// <param name="serverFilename"> </param> /// <param name="serverProfile"> </param> /// <param name="createOpenObjectServerIfNoRollbackLog"> </param> public static Sop.ObjectServerWithTransaction RollbackAll(string serverFilename, Preferences preferences, bool createOpenObjectServerIfNoRollbackLog) { if (string.IsNullOrEmpty(serverFilename)) { throw new ArgumentNullException("serverFilename"); } if (!Sop.Utility.Utility.HasRequiredDirectoryAccess(serverFilename)) { throw new InvalidOperationException( string.Format("Not enough rights/access on directory containing file '{0}'.", serverFilename)); } string serverRootPath = System.IO.Path.GetDirectoryName(serverFilename); if (string.IsNullOrEmpty(serverRootPath)) { serverRootPath = System.Environment.CurrentDirectory; } string[] appendLogs = null; if (preferences != null && preferences.MemoryExtenderMode) { if (Sop.Utility.Utility.FileExists(serverFilename)) { Sop.Utility.Utility.FileDelete(serverFilename); Sop.Utility.Utility.FileDelete(string.Format("{0}.{1}", serverFilename, ObjectServer.DataInfExtensionLiteral)); } } //** NOTE: ProcessUpdateLog needs to be done ahead of RollbackAll as the latter //** removes backup files which are used by the former //** rollback all pending transaction updates... ProcessUpdateLog(serverRootPath, true); //** Rollback (delete) root trans created DB objects... if (TransactionRoot.RollbackAll(serverRootPath)) { /** AppendLogxx.txt * Grow d:\Sopbin\Sop\File.dta 1050624 2096 */ appendLogs = Directory.GetFiles(serverRootPath, string.Format("{0}*.txt", AppendLogLiteral)); } #region Process append logs if (appendLogs != null && (createOpenObjectServerIfNoRollbackLog || appendLogs.Length > 0)) { if (Sop.Utility.Utility.FileExists(serverFilename)) { var r = new ObjectServerWithTransaction(serverFilename, null, preferences); r.Open(); foreach (string s in appendLogs) { ITransactionLogger trans = Transaction.BeginWithNewRoot(r); //** open the file and do restore for each backed up entry using (var sr = new StreamReader(s)) { while (sr.Peek() >= 0) { string l = sr.ReadLine(); if (l.StartsWith(GrowToken)) { int i1 = l.LastIndexOf(' '); int i2 = l.LastIndexOf(' ', i1 - 1); string s2 = l.Substring(i2, i1 - i2); long address; if (long.TryParse(s2, out address)) { string fName = l.Substring(GrowToken.Length, i2 - GrowToken.Length); var f = (OnDisk.File.IFile)r.GetFile(fName); if (f != null) { var dbi = new DeletedBlockInfo(); dbi.StartBlockAddress = address; int segmentSize; if (int.TryParse(l.Substring(i1), out segmentSize)) { dbi.EndBlockAddress = dbi.StartBlockAddress + segmentSize; if (f.DeletedCollections != null) { f.DeletedCollections.Transaction = trans; f.DeletedCollections.Add(dbi); } } } } } } } r.Flush(); trans.Commit(); //** remove the Backup log file, we're done rolling back and it's no longer needed Sop.Utility.Utility.FileDelete(s); } r.Dispose(); //return r; } else { foreach (string s in appendLogs) { Sop.Utility.Utility.FileDelete(s); } } } #endregion return(null); }
public TransferProcessor(ITransactionLogger transactionLogger, INotificationSender notificationSender) { this.transactionLogger = transactionLogger; this.notificationSender = notificationSender; }
public RecurringPaymentProcessor(ITransactionLogger transactionLogger) { this.transactionLogger = transactionLogger; }
/// <summary> /// Write data to disk in bulk mode. /// This method can spin off multiple threads part of doing Asynchronous operations /// to accomplish following processes: /// - back up existing target data segments that will be overwritten to respective transaction log file. /// - overwrite target data segments with data from in-memory source provided (source parameter). /// </summary> /// <param name="parent"></param> /// <param name="source"></param> /// <param name="dataChunks"></param> public void Write(Algorithm.Collection.ICollectionOnDisk parent, byte[] source, List <DataChunk> dataChunks) { Log.Logger.Instance.Log(Log.LogLevels.Information, "BulkWriter.Write begin."); byte[] data = source; ITransactionLogger trans = parent.Transaction; if (trans != null) { #region Async Backup target disk regions for update... using (var writePool = new ConcurrentIOPoolManager()) { using (var readPool = new ConcurrentIOPoolManager()) { foreach (var chunk in dataChunks) { // Identify regions that were not backed up and overwritten yet then back them up... ((TransactionBase)trans).RegisterSave((CollectionOnDisk)parent, chunk.TargetDataAddress, chunk.Size, readPool, writePool); } } } #endregion } #region Async write data segments from source onto respective target regions on disk... if (dataChunks.Count == 1 && dataChunks[0].Size <= (int)DataBlockSize.FiveTwelve) { var chunk = dataChunks[0]; long dataAddress = chunk.TargetDataAddress; int dataIndex = chunk.Index; int dataSize = chunk.Size; var writer = parent.FileStream; if (dataAddress != writer.Position) { writer.Seek(dataAddress, SeekOrigin.Begin); } writer.Write(data, dataIndex, dataSize); Log.Logger.Instance.Log(Log.LogLevels.Information, "BulkWriter.Write end (Size <= 512)."); return; } using (var writePool2 = new ConcurrentIOPoolManager()) { bool initial = true; foreach (var chunk in dataChunks) { long dataAddress = chunk.TargetDataAddress; int dataIndex = chunk.Index; int dataSize = chunk.Size; var writer = writePool2.GetInstance(parent.File.Filename, null, dataSize); // extend file if needed on initial step of the loop. long targetLastByteOnFileOffset = dataChunks[dataChunks.Count - 1].TargetDataAddress + dataChunks[dataChunks.Count - 1].Size; if (initial && writer.FileStream.Length < targetLastByteOnFileOffset) { initial = false; writer.FileStream.Seek(targetLastByteOnFileOffset, SeekOrigin.Begin); } if (dataAddress != writer.FileStream.Position) { writer.FileStream.Seek(dataAddress, SeekOrigin.Begin); } var param = new[] { null, writer }; writer.FileStream.BeginWrite(data, dataIndex, dataSize, Transaction.Transaction.WriteCallback, param); } } #endregion Log.Logger.Instance.Log(Log.LogLevels.Information, "BulkWriter.Write end."); }