Why am I getting a SnapshotNotFoundException when Spring WebFlow is starting? - spring-mvc

Ok all I am doing is trying to get to my 1st page. And I receive the following exception:
org.springframework.webflow.execution.repository.snapshot.SnapshotNotFoundException:
No flow execution snapshot could be found with id '1'; perhaps the snapshot has been removed?
I am using the following:
Spring Webflow 2.3 (with persistence-context flag)
Spring Security
Spring MVC
Spring-data
JPA 2.0, with/via custom JpaFlowExecutionListener
The only custom part of my JpaFlowExecutionListener is the part where I detach the EntityManager from the scope so it can serialize the flow - I have this as a database backed flow peristence setup. The flows are saved/read from/to the db ok. But I can't get it to render the first view.
From what I can tell here are the steps it goes thru prior to crashing below:
FlowExecutorImpl code calls launchExecution().
PersistentConversation is created.
PersistentConversation thread locked
PersistentConversation put into executionRepository and in PersistentConversationHolder's ThreadLocal Map of conversations. (keeps active thread's list of Conversations)
unlocks - causes a delete of the PersistentConversation in ThreadLocal Map
Then calls FlowExecutorImpl createPausedResult(flowExecution)
Which eventually calls FlowExecutorImpl resumeExecution().
Looks up PersistentConversation in PersistenceConversationHolder map using FlowID, but no longer finds PersistentConversation here.
Retrieves from the database and stuffs db object into a new PersistentConversation.
Attempts to resume Conversation from it's snapshot list but it was deleted in step 5.
For the PersistenceConversationHolder please reference example in this book here.
Any help would be so appreciated!

In case someone also misses this as I did...
At step #5 above when the Thread is unlocked, you need to update the save/update the PersistentConversation to the db, this copy will contain all the snapshot info.
Once I wrote this it was easy to see that there was a missing step.

Related

The configured execution strategy 'SqlRetryingExecutionStrategy' does not support user-initiated transactions

I have ASP.Net 4.7.2 window service which is processing NServiceBus messages. Currently it is deployed to On-Premise server. It has retry mechanism as well and working fine. Now I am going to containerizing it. While running into docker window container, it is doing SQL operation using Entity framework and giving exception as mentioned below:
The configured execution strategy 'SqlRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit.
While running locally by installing manually or on On-Premise server, it is working fine but in container it is throwing exception.
Can any one help me what can be the root cause?
It sounds like the piece of code does manual transaction management and is not wrapped within an execution strategy execute.
if your code initiates a transaction using BeginTransaction() you are defining your own group of operations that need to be treated as a unit, and everything inside the transaction would need to be played back shall a failure occur.
The solution is to manually invoke the execution strategy with a delegate representing everything that needs to be executed. If a transient failure occurs, the execution strategy will invoke the delegate again.
https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency#execution-strategies-and-transactions
using var db = new SomeContext();
var strategy = db.Database.CreateExecutionStrategy();
strategy.Execute(
() =>
{
using var context = new SomeContext();
using var transaction = context.Database.BeginTransaction();
context.SaveChanges();
transaction.Commit();
});
``

Symfony - background task from form setup

Would you know how to run a background task on Symfony 4, based on the setup of a form ? This would avoid that the user has to remain on the form until the task is finished.
The idea would be that when the form is validated, it starts an independant background task. Then the user can continue its navigation and come back once the task is finished to get the results.
Thanks for your help,
You need to use pattern Message Bus. Symfony has own implementation of this pattern since version 4.1 introducing Messenger Component.
You can see documentation here: https://symfony.com/doc/current/components/messenger.html
To get it work you need some external program that will implement AMQP protocol. Most popular in PHP world IMHO RabbitMQ.
A very simple solution for this could be the following procedure:
Form is valid.
A temporary file is created.
Cronjob gets executed every five minutes and starts a symfony command.
The command checks if the file exists and if it's empty.
If so, the command works of the background task. But before this, the command write it's process id in the file to prevent from beeing excuted a second time.
Remove the file when the command has finished.
As long as the file exists you can show a hint for the user that the task is running.

Firebase Transactions null or not updating the first time thru

I have clients connecting to the database with javascript.
I also have code running on my server and I'm trying to do a transaction following example as shown here:
https://firebase.google.com/docs/database/server/save-data#section-transactions
Here's a simplified structure of my data
users:
userguid
resource : "room1"
printer : "printer1"
resources
rooms
room1
printers
printer1
counter : 15
The web client would write a request to their own node under "users".
The server is watching for those request and updates the counter for that resource.
If i have the transaction watching for child added I get null for counter so I can't increment the number. If I also watch for child modified the I will get the correct counter value.
I understand from the documentation that the value in transaction can be null but I'm not sure how I can fix my use case to do what I need.
Basically I don't want the client touching the counter, I want the server to read and update that value.
I've gone thru this post
Firebase runTransaction not working
but I'm not clear on how to structure my code to deal with this.

How to get the user who initiated the process in IBM BPM 8.5?

How to get the user who initiated the process in IBM BPM 8.5. I want to reassign my task to the user who actually initiated the process. How it can be achieved in IBM BPM?
There are several ways to get that who initiated a Task , But who initiated a process Instance is somewhat different.
You can perform one out of the following :
Add a private variable and assign it tw.system.user_loginName at the POST of start. you can access that variable for user who initiated the process.(It will be null or undefined for the scenario if task is initiated by some REST API or UCA.)
Place a Tracking group after Start event . Add a input variable to it as username , assign it a value same as tw.system.user_loginName. So whenever Process is started entry will be inserted to DB Table.You can retrieve this value from that view in PerformanceDB.
Also there might be some table ,logging the process Instances details , where you can find the user_id directly.
I suggest you to look in getStarter() method of ProcessInstanceData API.
Official Documentation on API
This link on IBM Developerworks should help you too: Process Starter
Unfortunately there's not an Out Of The Box way to do this - nothing is recorded in the Process Instance that indicates "who" started a process. I presume this is because there are many ways to launch a process instance - from the Portal, via a Message Event, from an API call, etc.
Perhaps the best way to handle this is to add a required Input parameter to your BPD, and supply "who" started the process when you launch it. Unfortunately you can't supply any inputs from the OOTB Portal "New", but you can easilty build your own "launcher".
If you want to route the first task in process to the user that started the process the easiest approach is to simply put the start point in the lane, and on the activity select routing to "Last User In Lane". This will take care of the use case for you without requiring that you do the book keeping to track the user.
Its been a while since I've implemented this, so I can't remember if it will work elegantly if you have system steps before the first task, but this can easily be handled by moving the system steps into the human service to be executed as part of that call, rather than as a separate step in the BPD.
Define variable as string type and using script task to define the login user that use this task and assign it to your defined variable to keep to you in all of the process as initiator of the task.
You can use this line of code to achieve the same:
tw.system.user_loginName

Doctrine2: Cannot find concurrently persisted entity with findById

I have the current setup:
A regular Symfony2 web request can create and persist Job entity which also creates a Gearman Job, lets say this occurs in process 1. The Gearman Job is executed by a Gearman Worker which is passed the Job entity's ID.
I also use Symfony to create a Gearman Worker, this is run as a PHP CLI process, lets call this process 2.
For those not familiar with Gearman the worker code operates something like so:
for loop 5 times
get job from gearman (blocking method call)
get job entity from database
do stuff
Essentially this code keeps a Symfony2 instance running to handle 5 Jobs before the worker dies.
My issue is this: On the first job that the worker handles Doctrine2 is able to retrieve the created job from the database without issue using the following code:
$job = $this->doctrine
->getRepository('AcmeJobBundle:Job')
->findOneById($job->workload()); // workload is the job id
However, once this job completes and the for loop increments to wait for a second job, lets say this arrives from another Symfony2 web request on process 3 creating the Job with ID 2, the call to the Doctrine2 repository returns null even though the entity is definitely in the database.
Restarting the worker solves the issue, so when it carries out it's first loop it can pick up Job 2.
Does anyone know why this happens? Does the first call of getRepository or findOneById do some sort of table caching from MySQL that doesn't allow it to see the subsequently added Job 2?
Does MySQL only show a snapshot of the DB to a given connection as long as it is held open?
I've also tried resetting the entityManager before making the second call to findOneBy to no avail.
Thanks for any advice in advance, this one is really stumping me.
Update:
I've created a single process test case to rule out whether or not it was the concurrency causing the problem, and the test case executes as expected. It seems the only time the repository can't find job 2 is when it is added to the DB on another process.
// Job 1 already exists
$job = $this->doctrine
->getRepository('AcmeJobBundle:Job')
->findOneById(1);
$job->getId(); // this is fine.
$em->persist(new Job()); // creates job 2
$em->flush();
$job = $this->doctrine
->getRepository('AcmeJobBundle:Job')
->findOneById(2);
$job->getId(); // this is fine too, no exception.
Perhaps one process tries to load entity before it has saved by the second process.
Doctrine caches loaded entities by their id, so that when you get a second request for the same object it loads without making another query to the database. You can reed more about Doctrine IdentityMap here

Resources