示例#1
0
 static void ProcessFinally(AppWorkflow aw /*,IProfiler profiler*/)
 {
     if (aw == null)
     {
         return;
     }
     aw._endEvent.WaitOne(_wfTimeSpan);
     if (aw._unhandledException != null)
     {
         if (aw._unhandledException.InnerException != null)
         {
             throw aw._unhandledException.InnerException;
         }
         throw aw._unhandledException;
     }
     if (aw._application.InstanceStore != null)
     {
         aw._application.InstanceStore.DefaultInstanceOwner = null;
     }
     aw.WriteTrackingRecords();
     aw.Dispose();
     aw = null;
     //TODO:if (profiler != null)
     //profiler.EndWorkflow(aw._token);
 }
示例#2
0
        public static void ResumeWorkflowTimer(IApplicationHost host, IDbContext dbContext, IMessaging messaging, Int64 processId)
        {
            AppWorkflow aw     = null;
            var         result = new WorkflowResult
            {
                InboxIds = new List <Int64>()
            };

            try
            {
                var      pi   = ProcessInfo.Load(dbContext, processId, 0);
                var      def  = WorkflowDefinition.Load(pi);
                Activity root = def.LoadFromDefinition();
                aw = Create(dbContext, root, null, def.Identity);
                aw._application.Extensions.Add(dbContext);
                aw._application.Extensions.Add(messaging);
                aw._application.Extensions.Add(host);
                aw._application.Extensions.Add(result);
                WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(pi.WorkflowId, aw._application.InstanceStore);
                aw._application.Load(instance, _wfTimeSpan);
                aw._application.Run(_wfTimeSpan);
            }
            catch (Exception ex)
            {
                if (!CatchWorkflow(aw, ex))
                {
                    throw;
                }
            }
            finally
            {
                ProcessFinally(aw);
            }
        }
示例#3
0
        public static async Task <WorkflowResult> StartWorkflow(IApplicationHost host, IDbContext dbContext, IMessaging messaging, StartWorkflowInfo info)
        {
            AppWorkflow aw       = null;
            var         profiler = host.Profiler;
            var         result   = new WorkflowResult
            {
                InboxIds = new List <Int64>()
            };

            try
            {
                WorkflowDefinition def     = null;
                Activity           root    = null;
                Process            process = null;
                using (profiler.CurrentRequest.Start(ProfileAction.Workflow, $"Load '{info.Source}'"))
                {
                    def     = WorkflowDefinition.Create(info.Source);
                    root    = def.LoadFromSource(host, dbContext);
                    process = Process.Create(def, info);
                }
                // workflow arguments
                IDictionary <String, Object> args = new Dictionary <String, Object>
                {
                    { "Process", process },
                    { "Comment", info.Comment }
                };
                aw = Create(dbContext, root, args, def.Identity);
                aw._application.Extensions.Add(result);
                aw._application.Extensions.Add(dbContext);
                aw._application.Extensions.Add(messaging);
                aw._application.Extensions.Add(host);
                process.DbContext  = dbContext;
                process.WorkflowId = aw._application.Id;
                await process.Start(dbContext);

                using (profiler.CurrentRequest.Start(ProfileAction.Workflow, $"Run. Process.Id = {process.Id}, Workflow.Id={process.WorkflowId}"))
                {
                    aw._application.Run(_wfTimeSpan);
                    result.ProcessId = process.Id;
                    return(result);
                }
            }
            catch (Exception ex)
            {
                if (!CatchWorkflow(aw, ex))
                {
                    throw;
                }
                return(result);
            }
            finally
            {
                ProcessFinally(aw);
            }
        }
示例#4
0
        public static async Task <WorkflowResult> ResumeWorkflow(IApplicationHost host, IDbContext dbContext, ResumeWorkflowInfo info)
        {
            AppWorkflow aw     = null;
            var         result = new WorkflowResult
            {
                InboxIds = new List <Int64>()
            };

            try
            {
                InboxInfo inbox = await InboxInfo.Load(dbContext, info.Id, info.UserId);

                result.ProcessId = inbox.ProcessId;
                var      def  = WorkflowDefinition.Load(inbox);
                Activity root = def.LoadFromSource(host);
                aw = Create(dbContext, root, null, def.Identity);
                aw._application.Extensions.Add(result);
                aw._application.Extensions.Add(dbContext);
                WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(inbox.WorkflowId, aw._application.InstanceStore);
                aw._application.Load(instance, _wfTimeSpan);
                foreach (var bm in aw._application.GetBookmarks())
                {
                    if (bm.BookmarkName == inbox.Bookmark)
                    {
                        var rr = new RequestResult
                        {
                            Answer  = info.Answer,
                            Comment = info.Comment,
                            Params  = info.Params,
                            UserId  = info.UserId,
                            InboxId = info.Id
                        };
                        aw._application.ResumeBookmark(bm.BookmarkName, rr);
                        return(result);                        // already resumed
                    }
                }
                // if a bookmark is not found
                aw._application.Unload();
            }
            catch (Exception ex)
            {
                if (!CatchWorkflow(aw, ex))
                {
                    throw;
                }
            }
            finally
            {
                ProcessFinally(aw);
            }
            return(result);
        }
示例#5
0
        protected override void Execute(NativeActivityContext context)
        {
            Boolean          waitComplete = WaitComplete.Get <Boolean>(context);
            IDbContext       dbContext    = context.GetExtension <IDbContext>();
            var              messaging    = context.GetExtension <IMessaging>();
            IApplicationHost host         = context.GetExtension <IApplicationHost>();

            context.DoTrack(dbContext, TrackBefore.Get <TrackRecord>(context));
            context.DoModelState(dbContext, StateBefore.Get <ModelStateInfo>(context));

            var pi = ProcessInfo.Get <StartProcessInfo>(context);

            String bookmark = null;
            var    process  = Process.GetProcessFromContext(context);

            if (waitComplete)
            {
                bookmark = Guid.NewGuid().ToString();
                var wfResult = context.GetExtension <WorkflowResult>();
                // TODO: WAIT COMPLETE FOR CHILDREN
                //Int64 pid = process.CreateChildren(dbContext, kind, docId, bookmark, Mark.Get<String>(context));
            }

            var sfi = new StartWorkflowInfo()
            {
                UserId     = process.Owner,
                Source     = pi.Workflow,
                DataSource = pi.DataSource,
                Schema     = pi.Schema,
                Model      = pi.ModelName,
                ModelId    = pi.ModelId,
                ActionBase = pi.ActionBase,
                Parent     = process.Id
            };

            var task = AppWorkflow.StartWorkflow(host, dbContext, messaging, sfi);

            task.Wait();
            WorkflowResult result = task.Result;

            if (waitComplete)
            {
                context.CreateBookmark(bookmark, new BookmarkCallback(this.ContinueAt));
            }
            else
            {
                Result.Set(context, String.Empty);
            }
        }
示例#6
0
        static AppWorkflow Create(IDbContext dbContext, Activity root, IDictionary <String, Object> args, WorkflowIdentity identity)
        {
            var aw    = new AppWorkflow();
            var store = aw.CreateInstanceStore(dbContext.ConnectionString(null));

            if (args == null)
            {
                aw._application = new WorkflowApplication(root, identity);
            }
            else
            {
                aw._application = new WorkflowApplication(root, args, identity);
            }
            aw.SetApplicationHandlers();
            aw._dbContext = dbContext;
            aw._tracker   = StateMachineStateTracker.Attach(aw._application);
            aw._application.Extensions.Add(new WorkflowTracker(aw));
            aw._application.InstanceStore = store;
            return(aw);
        }
示例#7
0
 static Boolean CatchWorkflow(AppWorkflow aw, Exception ex)
 {
     if ((aw != null) && (aw._application != null))
     {
         String msg = ex.Message;
         if (ex.InnerException != null)
         {
             msg = ex.InnerException.Message;
         }
         aw.Track(new CustomTrackingRecord(aw._application.Id, msg, TraceLevel.Error));
         aw._application.Unload();
     }
     if (ex.InnerException != null)
     {
         throw ex.InnerException;
     }
     else
     {
         return(false);
     }
 }
示例#8
0
 public WorkflowTracker(AppWorkflow workflow)
 {
     _workflow = workflow;
 }
示例#9
0
 public async Task <WorkflowResult> ResumeWorkflow(ResumeWorkflowInfo info)
 {
     return(await AppWorkflow.ResumeWorkflow(_host, _dbContext, _messaging, info));
 }
示例#10
0
        public static async Task <WorkflowResult> ResumeWorkflow(IApplicationHost host, IDbContext dbContext, IMessaging messaging, ResumeWorkflowInfo info)
        {
            AppWorkflow aw       = null;
            var         profiler = host.Profiler;
            var         result   = new WorkflowResult
            {
                InboxIds = new List <Int64>()
            };

            try
            {
                InboxInfo inbox = await InboxInfo.Load(dbContext, info.Id, info.UserId);

                if (inbox == null)
                {
                    throw new WorkflowException("The task is already done by another user");
                }
                using (profiler.CurrentRequest.Start(ProfileAction.Workflow, $"Load '{inbox.Kind}'"))
                {
                    result.ProcessId = inbox.ProcessId;
                    var      def  = WorkflowDefinition.Load(inbox);
                    Activity root = def.LoadFromSource(host, dbContext);
                    aw = Create(dbContext, root, null, def.Identity);
                    aw._application.Extensions.Add(result);
                    aw._application.Extensions.Add(dbContext);
                    aw._application.Extensions.Add(messaging);
                    aw._application.Extensions.Add(host);
                    WorkflowApplicationInstance instance = WorkflowApplication.GetInstance(inbox.WorkflowId, aw._application.InstanceStore);
                    aw._application.Load(instance, _wfTimeSpan);
                }
                foreach (var bm in aw._application.GetBookmarks())
                {
                    if (bm.BookmarkName == inbox.Bookmark)
                    {
                        var rr = new RequestResult
                        {
                            Answer  = info.Answer,
                            Comment = info.Comment,
                            Params  = info.Params,
                            UserId  = info.UserId,
                            InboxId = info.Id
                        };
                        using (profiler.CurrentRequest.Start(ProfileAction.Workflow, $"Resume '{bm.BookmarkName}'"))
                        {
                            aw._application.ResumeBookmark(bm.BookmarkName, rr);
                        }
                        return(result);                        // already resumed
                    }
                }
                // if a bookmark is not found
                aw._application.Unload();
            }
            catch (Exception ex)
            {
                if (!CatchWorkflow(aw, ex))
                {
                    throw;
                }
            }
            finally
            {
                ProcessFinally(aw);
            }
            return(result);
        }
示例#11
0
        void ProcessPendings(Int32 wakeupCount, IBackgroundTasksManager manager, String parameter)
        {
            IList <PendingWorkflow> list = null;

            try
            {
                manager.Logger.LogBackground("Loading pending workflows");
                var prms = new ExpandoObject();
                prms.Set("Count", wakeupCount);
                if (parameter != null)
                {
                    prms.Set("Parameter", parameter);
                }
                list = manager.DbContext.LoadList <PendingWorkflow>(String.Empty, "a2workflow.[Process.Pendings]", prms);
                if (list == null)
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                String msg = ex.Message;
                if (ex.InnerException != null)
                {
                    msg = ex.InnerException.Message;
                }
                manager.Logger.LogBackgroundError(msg);
            }
            if (list.Count <= 0)
            {
                return;
            }

            manager.Logger.LogBackground($"{list.Count} item(s) loaded");
            try
            {
                foreach (var pw in list)
                {
                    // local data needed
                    var wfId   = pw.WorkflowId;
                    var pId    = pw.ProcessId;
                    var wfAuto = pw.AutoStart;

                    manager.ScheduleBackgroundTask(() =>
                    {
                        if (wfAuto)
                        {
                            manager.Logger.LogBackground($"Autostarting process. ProcessId = {pId}");
                            AppWorkflow.AutoStart(pId, manager.Logger);
                        }
                        else
                        {
                            // resume timer
                            manager.Logger.LogBackground($"Resuming timer. ProcessId = {pId}");
                            AppWorkflow.ResumeWorkflowTimer(manager.Host, manager.DbContext, manager.Messaging, pId);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                String msg = ex.Message;
                if (ex.InnerException != null)
                {
                    msg = ex.InnerException.Message;
                }
                manager.Logger.LogBackgroundError(msg);
            }
        }
示例#12
0
 public async Task <WorkflowResult> StartWorkflow(StartWorkflowInfo info)
 {
     return(await AppWorkflow.StartWorkflow(_host, _dbContext, info));
 }