I've a windows workflow service that is hosted in a console application. I have a count variable in the service and the value is incremented in each call, how I can make the count value to be persistent between calls.
EDITED: The workflow takes a timeout value as input and returns an id. If you pass 10 as the timeout value the workflow delays for 10 seconds and return the id 1. In between if another client pass 3 as the timeout value a new instance of workflow has to be created and it has to wait for 3 seconds returning the new id value as 2.
If you are referring to a variable per workflow instance you can create a variable at the root sequence of you workflow and store. If the workflow is persisted to disk this variable will be saved with it.
However from you question it seems you are referring to a variable per workflow type. In that case there is no static variable per workflow type and you need to manage the state outside of the workflow and persist it yourself.
Related
I have built a micro-service where there is an API called deleteToken. This API(when invoked) is supposed to change the status in a tuple in db corresponding to token (identified with token id) to "MARK-DELETE". Once that tuple has status "MARK_DELETE" then after 30 days there should be a rest call made to downstream service API called deleteTokenFromPartner. There is no such mandate like call to deleteTokenFromPartner has to be made right after 30 days, it can be done few hours later 30 days also. So what I thought was I will write a scheduler (using Quartz, Java Executor service) with scheduled period in such a way that it will run once everyday. what it will do is it will query db and find out all rows which has status="MARK_DELETE" and status update is older than 30 days. After then it will iteratively call deleteTokenFromPartner for each and every row. There is one db which is highly available and we may not have any issue with consistency as we delete after 30 days. But the problem I am seeing is, as this is a micro-service which has N instances so every instance will query db, get the same set of rows and make call to same rows. Can I make any tweak so that this duplicated calls can be avoided. FYI we don't make any config changes using hostnames and if only one instance will be capable of running the scheduler that too will be fine.
I'm currently using Data Factory V1.
I have a pipeline with 2 chained activities:
. The first activity is a Copy Activity that extracts a table from SQLDB into a .tsv file in Data Lake Store
. The second activity is a Data Lake Analytics U-SQL activity that collects the data in the previously created .tsv file and adds it to an existing table in Data Lake database.
Obviously, I only want the second activity to run after the first activity so I used the output dataset from the first activity as the input data to the second activity and it works fine.
But, if the first activity fails, the second activity will be stuck at the state "Waiting: Dataset dependencies (The upstream dependencies are not ready)".
I have the policy->timeout property set for the second activity but it only seems to work after this activity has started. So, since the activity never starts, it doesn't timeout and it stays stuck.
How can I set a timeout for this "waiting" period?
Thank you
That is how v1 works. If your upstream dataset fails, the second will stay in the waiting state until the first dataset has completed successfully.
If you are using a schedule, you would want to fix the problem with the first activity and run the failed slice again. If you're working with a one-time pipeline, you have to run the whole pipeline again after fixing the problem.
The timeout only works when the processing actually starts, as is written in de Data Factory documentation.
If the data processing time on a slice exceeds the timeout value, it is canceled, and the system attempts to retry the processing. The number of retries depends on the retry property. When timeout occurs, the status is set to TimedOut.
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
We receive many large data files daily in a variety of formats (i.e. CSV, Excel, XML, etc.). In order to process these large files we transform the incoming data into one of our standard 'collection' message classes (using XSLT and a pipeline component - either built-in or custom), disassemble the large transformed message into individual 'object' messages and then call a series of SOAP web service methods to handle business logic and database operations.
Unlike other files received, the latest file will contain all data rows each day and therefore, we have to handle the differences to prevent identical records from being re-processed each day.
I have a suitable mechanism for handling inserts and updates but am currently struggling with the deletes (where the record exists in the database but not in the latest file).
My current thought process is to flag the deleted records in the database using a 'cleanup' task at the end of the entire process but this would require a method to be called once all 'object' messages from the disassembled file have completed.
Is it possible to monitor individual messages from a multi-record file and call a method on completion of the whole file? Currently, all research is pointing to an orchestration with some sort of 'wait' but is this the only option?
Example: File contains 100 vehicle records. This is disassembled into 100 individual XML messages which are processed using 100 calls to a web service method. Wish to call cleanup operation when all 100 messages are complete.
The best way I've found to handle the 'all rows every day' scenario is to pre-stage the data in SQL Server where it's easier to compare the 'current' set to the 'previous' set. The INTERSECT and EXCEPT operators make it pretty easy in most cases.
Then drain the records with a Polling statement.
The component that does the de-batching would need to publish a start of batch message with the number of individual records and a correlation key.
The components that do the insert & update would need to publish a completion message with the same correlation key when it is completed processing.
The start of batch message would have spun up an Orchestration that would would listen for the completion messages with that correlation key and count the number, and either after it has received the correct number or after a timeout period it would call the cleanup or raise an exception.
I have an Activity( waiting for an approval ) that contains a WhileActivity. In the while activity I want to read the value of an argument - if it returns true I execute I continue with workflow execution, otherwise I stop the hanging the executing till the argument value turns true
How can I do this - for a while or other activities - ?
Thank you
If the value you are waiting on is being changed by another activity you can use a TrackingParticipant to watch for the value changing and when that happens resume a bookmark to notify your waiting activity.
Sounds more like your requirements would be better served by a State Machine workflow.
Okay, so you don't want to use a State Machine workflow. So, here's how you do it.
You have to create a custom Activity that is used in conjunction with a Workflow Extension. An Extension is just an object that can be accessed by your Activities as the workflow executes and allows your Activities to communicate with the classes that are executing the workflow.
Your custom Activity must be able to create a Bookmark and offload the Workflow. It does this while you wait for the correct value from your Extension. You don't need to do this in any While Activity loop. You just do the following
Get your Extension
Get the current value you are evaluating on
If you aren't happy, create a bookmark
When the bookmark resumes, go to step 1.
If you are happy, continue execution.