This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Where is the transaction cache in VAF task queue?

Task queues in Vault Application Framework applications (m-files.com)

I am using a task queue to replicate the document into an external system and I need to keep a reference to that system id.

Usually I put that id into a document property and I use the transaction cache to prevent other event handler to trigger on the document (aka MultiChangePreventor in CK).

Unfortunately the samples using task queue do not have any environment variables as method parameter, unlike event handler.
Is there any way I can have access to the transaction cache to prevent my task queue and handlers to call each other indefinitely ?

  • You're correct, but did you try the approach I showed?  You can declare a variable for the exception before the commit call, then reference that outside.  Note in my code sample I wasn't using "catch(Exception e)" - the variable was declared higher up.

    For clarity:

    // Declare "e" here.
    Exception e = null;
    
    try
    {
        job.Commit((transactionalVault) =>
        {
            // Create the exception to throw, and store in e...
            e = new AppTaskException(TaskProcessingJobResult.Retry, "hello world");
            
            // ...then throw e.
            throw e;
        });
    }
    catch(Exception restoredException)
    {
        // Notice that this catches "restoredException", but "e" is declared on line 2.
        // "restoredException" will contain the restored exception, which may not be as useful.
        // "e", though, will contain the exact exception that you threw inside your code.
        // This means you can do whatever you want with the exception including logging
        // and re-throwing to control task re-queuing and the like.
    }

  • Yeah I did and got my exception.

    Now I am trying to implement a notification when a task fails (ie at the fatal stage, I do not want to be notify if it get requeued or retried). I was thinking about using NLOG email setting for that.

    My general idea is to use the TaskManager event because I have several tasks and want a central place to handle that.

    protected override void InitializeTaskManager()
    {
        base.InitializeTaskManager();
    
        if (TaskManager != null)
        {
            //LogManager.EnableLoggingToAttachedDebugger(true);
    
            TaskManager.TaskEvent += (s, e) =>
            {
                // When my task fails, log a fatal error
                if (e.EventType == TaskManagerEventType.TaskJobFinished && e.JobResult == TaskProcessingJobResult.Fatal && e.Queues.Safe().Contains(MyTaskQueueId))
                    Logger.Fatal(e.Exception, $"TEST");
            };
        }
    }

    Unfortunately it seems that the Job.Exception is not carried on the task event (e.Exception is always null).
    I can still find most of my needed info in the JobStatus ErrorMessage and JobStatus.StackTrace.

    Maybe you can add some kind of improvement here

    // THIS IS FROM TaskQueueProcessor CLASS
    
    private void JobDone(Task<TaskProcessingJobResult> task, TaskProcessingJob job)
    {
    	EnterWriteLock();
    	try
    	{
    		activeJobs.Remove(job.TaskInfo.TaskID);
    	}
    	finally
    	{
    		ExitWriteLock();
    	}
    	taskCompletedSinceLastPoll = true;
    	
    	// MAYBE ADD THE job.Exception TO THE TaskManagerEventArgs CONSTRUCTOR
    	Manager.TriggerTaskEvent(new TaskManagerEventArgs(TaskManagerEventType.TaskJobFinished, new string[1] { Id }, null, new ApplicationTaskInfo[1] { job.TaskInfo }, null, job.GetStatus(), task.Result));
    }