We’re encountering strange behaviour while testing our process. We have a model (built in Modeler) with some underlying flow services.
The problem we are encountering is as follows:
We are entering new data for each of our tests. For each test, this data is visible in the pipeline for half of the steps in the Model. But suddenly, after a join in the Model, all the remaining steps contain the pipeline data of the PREVIOUS execution.
The only way we can resolve this at present is to restart the IS and then run the test again. Then we see the data from our latest test in the whole pipeline - as we would expect. However, if we run another test, we once again see the data from the last execution pop up in the middle of the pipeline, at our join step.
Has anybody encountered this before or have any idea what may be causing this phenomenon?
The ‘Cache Results’ property of one of our Flow Services was set to True. It was therefore caching the return values of the Flow Service. We set this to False and our problem was solved. See screenshot.
Easy when you know how right?!
By the way, to get to the Properties of a Flow Service do the following:
Make sure you’re in the 3-panel view, i.e. with Navigaton on the left, Properties on the right, and the active item in the middle
Double-click your Flow Service in Developer on the Left-hand side to make it active.
Click in the whitespace in the middle panel, and the Properties of the Flow Service appear in the Propeties panel on the right-hand side.
(keywords: developer stuck same data previous execution cache cached thread)
The trick with cacheing a Flow service is to use “pub.flow:clearPipeline” as the last step in the cached service, setting the “preserve” list to include only the values your service will return.
As you would notice from stepping through Flow code, the entire pipeline from previous steps is passed in to your Flow service - and any variables you create and don’t explicitly drop are returned from it. Good pipeline management is an important part of good Flow coding, and will help with performance too.
Why you need to do a “clearPipeline” is tied up with how cacheing and pipeline management work.
Under the covers, a pipeline is effectively a Java Map of name/value pairs. Each Flow service “invoke” creates a new Map, copying the entire contents of the current pipeline - then invokes the service. The invoked service adds/removes variables from the copied pipeline - returning the updated pipeline. The updated pipeline is then merged with the original pipeline (so new variables are added and existing variables are over-written). Variables that you drop in the invoked service have no effect on the merged pipeline - they simply aren’t there to merge.
When a service is cached, the cache is just a lookup table with the name of the service and the input values it was called with, pointing to a saved pipeline of the output from the service the first time it was invoked. When a service which has been cached is invoked, the cache manager simply hands back a copy of the saved pipeline which is then merged with the current pipeline.
As you discovered, this sometimes has unintended results! I found this out the hard way when I tried to cache an adapter service call and started processing the same sales order over and over again…
Anyway, if you do a clearPipeline as the last step in your cached service then the pipeline to be merged will ONLY contain the variables you want to be merged. (And if you want to cache an adapter service call, write a Flow wrapper that calls the adapter service and does the clearPipeline!)
Steve-
I was told something similar about using the pub.flow:clearPipeline service in cached services, except I was told to do it as the first step of the service, preserving the inputs. Not only will this prevent sending junk to the calling service, it will keep any junk that was passed to the cached service from being stored in the cache, saving memory.
Only what you map as input is passed to the flow step
None of the variables you create in the flow service will be passed to the calling flow service. (no need for clearPipline in the called service)
Only the the mapped variables from output of the called service will be in the pipeline.
Only downside is you have to look at the pipeline tab to see what service is called.(You can add the name of the service in the comment, but you cannot rely on that while debugging)
This is true. But how do i make the modified variable in the called service not to appear in the caller service again at runtime?
I used pub.flow.clearPipeline as the last step (preserving only the output variables though) and i even manually dropped that particular variable in the called service. But when i step out of the called flow service, i still see the variable with the modified values in the pipeline. Problem here is, I’m using the same variable both in called service and caller service which i cannot change now for whatever reason. When i try to use that variable again in my calling service it was already modified and i cannot use it no longer. I know that i can hardcode the value again for that variable in my calling service before i can use it. But I’m trying to find a any other work around for this. Can any one help me in this case??? Please.
In the calling service, map the variable that you want to keep unchanged to a temp var. After calling the child service, map the temp var back to the original name.
Call the child service in a scope. This will hide your var from the child service.
Call the child service as a transformer. This will also hide your var from the child service.
Based on the webMethods Developer Users Guide 65.pdf , page 402, Invoke Step. I carried out the following steps to see the usage of “Scope” property in a flow service
Calling service
map ( set var1)
Invoke Called service( pass var1) called service:
input var1
debuglog (display var1)
Scoped scenarios
Calling service
map ( set var1 - Test Scope)
Invoke Called service( pass var1)
set the Scope property as document name(Test value). and ran the service. the variable is not passed to called service
I got the output as Test value → message: %var1%
2.Normal scenario
calling Service
map(set var1 -Test Scope)
Invoke called Service(pass var1)
I got the output as message : Test Scope
here comes my doubt, I’m giving the scope to the called service as Test value. and getting different output. I’m not able to conclude , on the exact usage of the scope property. would appreciate if you explain more.