private MainApplicationContext InitializeResponse(Action <Journals.Journal> action, CancellationToken token) { // [DM] This is a quick workaround to fix multithreading issues caused by original non-thread-safe legder code. // When ExecuteCommandWrapper is executing, it changes the state of GlobalScope object, it can also change the state of // accounts and xacts (depending on the command). However, it properly restores the original state when it finishes. // Therefore, the quick solution is to limit parallel requests with only one running executor at the moment. // The right solution would be cloning GlobalScope object for every thread (or, fixing thread-unsafe code). lock (ServiceSession) { using (var memoryStreamManager = new MemoryStreamManager()) { var context = ServiceSession.ServiceEngine.CloneContext(ServiceSession.MainApplicationContext, memoryStreamManager); token.Register(() => context.CancellationSignal = CaughtSignalEnum.INTERRUPTED); context.Logger = new Logger(); context.ErrorContext = new ErrorContext(); using (context.AcquireCurrentThread()) { var scope = ServiceSession.GlobalScope; try { Status = 1; scope.PushReport(); action(ServiceSession.GlobalScope.Session.Journal); scope.PopReport(); Status = 0; } catch (CountError errors) { Status = errors.Count; } catch (Exception err) { scope.PopReport(); scope.ReportError(err); } OutputText = memoryStreamManager.GetOutputText(); ErrorText = memoryStreamManager.GetErrorText(); return(context); } } } }
private MainApplicationContext InitializeSession(IEnumerable <string> args, CancellationToken token) { using (var memoryStreamManager = new MemoryStreamManager(InputText)) { var context = ServiceEngine.CreateContext(memoryStreamManager); token.Register(() => context.CancellationSignal = CaughtSignalEnum.INTERRUPTED); using (context.AcquireCurrentThread()) { GlobalScope.HandleDebugOptions(args); Logger.Current.Info(() => LedgerSessionStarting); GlobalScope = new GlobalScope(context.EnvironmentVariables); GlobalScope.Session.FlushOnNextDataFile = true; try { // Look for options and a command verb in the command-line arguments BindScope boundScope = new BindScope(GlobalScope, GlobalScope.Report); args = GlobalScope.ReadCommandArguments(boundScope, args); GlobalScope.Session.ReadJournalFiles(); Status = 0; } catch (CountError errors) { Status = errors.Count; } catch (Exception err) { GlobalScope.ReportError(err); } OutputText = memoryStreamManager.GetOutputText(); ErrorText = memoryStreamManager.GetErrorText(); return(context); } } }