I have a function that is chained together with another transaction. The first transaction creates an order, then creates a record. The second transaction reads that record and calls a web service with its contents.
I am running into a scenario where the second transaction executes so fast that the web service (which has been sent a response from the first transaction) hasn’t read the response from the first.
That is a long way to say; can I slow down the execution of my custom code with a timer or something?
Sounds like you are Asynchronous when you want to be synchronous…
How are the two transactions called?
Well to my understanding functions are synchronous and since it’s chaining one function to another, they are firing very fast.
I’d like to put sometime around my http client inside my second function to perhaps put a one or two second delay before calling the web service with it.
You could do a Thread.Sleep(2000) call in the second function then…
I tried that but it didn’t seem to be available inside an epicor Function…I’ll try again.
This might lockup the UI. I think there is a way to do the same with Task which wont lock up the UI.
Since these all run on the server there probably will be a thread I can use but perhaps a timer instantiating would work too? I’ve probably overlooked something simple in these potentials
Thread.Sleep() will pause the code for the given time but it will also pause anything else running on the same thread so generally not the best solution.
You can do await Task.Delay(2000) which will not block but increases the complexity by adding async into the code. see c# - Wait some seconds without blocking UI execution - Stack Overflow.
From what I understand you would be best to either use the Task.Delay() or look at making the calls synchronous (ie make sure the second call waits for the first one to finish). How is the second function called?
It’s just being invoked at the end of execution on the first function via the invoke function widget. I agree putting it there makes the most sense. I’ll try that out and report back
This was the winner. Although, even setting it to a 15 second delay didn’t solve my problem. Hitting the same url I am generating from a browser works just fine and the service updates the things it needs to.
But thank you for pointing me in the right direction:)
Ok there’s a little more to it than I thought. By chaining two functions together i.e. invoking a function inside the first function, the entire thing is bundled together. The original HTTP request off the first function will not receive a response until after the second function has executed, so putting a wait into the second function only serves to delay the first function returning a response to the client.
My two thoughts are to write the record in my first function and then set up some polling mechanism to read for that record and process it, but I don’t really like this approach.
The second thought is to set up a surgical method execution inside the first function, say “GetByID” on ABCCode or something, and pass in a very specific call context value. Then, building a method directive on that BO Method to listen for the specific call context value and then execute the second function. It’s a stretch and more overhead than I’d like but I’m definitely open to other ideas.
Where are you calling the functions from?
The first function is called from a web application that calls a web API that calls the function. This (without any of the complexity above) creates a Quote in the ERP and returns back a quote number to the calling application through the web api
Can you post that code block of the calls being made.
This is without the invoke 2nd function code fyi
I mean the call from the web app
oh, that’s all done just with a basic curl command on the server hosting that application and I didn’t write it.
so the web app calls the function via rest. function 1 runs and function 1 calls function 2
Essentially yes. Web app calls web api (acting as a broker between web app and epicor), web api calls Epicor function. Epicor function 1 called Epicor function 2, but with this Epicor function 2 executes on the same thread as epicor function 1. So Epicor function 2 has to finish before allowing Epicor function 1 to finish and return response through web api to we app
If Epicor function 2 could be called asynchronously that would solve it, but it seems that all of the functions and code blocks within the function are all synchronous
Hmm i’m still not following how this is setup. If web app calls first function async and first function calls second within Epicor you should never have run into a race condition.