Controlling Java and Lotusscript agents - java

I created 2 agents, one made of Java and another made of Lotusscript. The java agent is scheduled to run every 5 minutes, while the lotusscript agent is scheduled to run every 15 minutes. Therefor there will come a time that they will simultaneously run. When that happens, the java agent must pause/wait until the lotusscript agent finished. I tried to simulate locking using Profile DOcuments and Environment Variables but to no avail. Is there a way that I can simulate locking between this two different agents? Please help. Thanks a lot!
Edit: I forgot to say that the 2 agents resides in TWO DIFFERENT databases, to complicate things more :(

Why not writing a third Agent (maybe in an extra Database), which runs periodically every five Minutes, which starts the other two Agents:
The Lotus Script Agent every time
The Java Agent every third run
... then you are also in control of the run order, without any complicated lock mechanisms.

This is a near foolproof way I have found that works for controlling the execution order of independent agents. I use a real notes document as a psuedo-lock document.
The way I have done this before is to keep a Notes document that represents a "lock". Don't use a database profile document as it's prone to replication/save conflict issues and you can't view it in a view.
The "lock" document can have a flag on it which tells the java agent whether it is allowed to run now. The java agent simply has code in it similar to this
Session s = NotesFactory.createSession();
Database db = s.getDatabase("This Server", "This database");
View vw = db.getView("(lockView)");
Document docControl = vw.getFirstDocument();
String sRunStatus = docControl.getItemValueString("runStatus");
boolean bContinue = false;
if (sRunStatus =="Go"){
bContinue = true;
}
if(bContinue){
//do agent code here....
// reset the status to "wait". The lotusscript agent should then set it to "Go"
// the other agent will execute on "wait" and then update the status to "Go" on
// completion to prevent simulatenous execution. Can also use different state names
// instead of go/wait, like run0, run1, run2 etc
docControl.replaceItemValue("runStatus", "wait");
docControl.save(true);
}
Note that you use the agents to set "Go"/"wait" values in the "runStatus" field on a control document. You only need 1 document so you then only need to get the first document out of the view.
The equivalent logic should be even simpler to add in the LotusScript agent as well. The only downside I can find is that the java agent may not execute the code because the control document is not yet set to "go" and the "IF" test fails without running the logic, so it's not a pause as such, but prevents the Java agent from executing out of it's desired order with the lotusscript agent. But it would then fire on the next scheduled instance if the LotusScript agent has released it.
You can also extend this idea to manage a suite of agents and even chain multiple agents as well by using specific values like "RunAgent1", "RunAgent2", another benefit is that you can also capture execution start times, errors as well, or anything you require....

Enabling document locking in the database could work. If you can enable document locking in the database itself you can have the agents lock a specific document and check if the document is locked before/during it runs the code.
If enabling document locking in that database is not an option you can consider creating a separate database do store the document.
Why can't these agents run simultaneously? Maybe it is possible to achieve the same result while allowing the agents to run simultaneously. Trying to control agents this way will usually lead to other problems. If the database has replicas the solution might break.

You said that it is two databases, but really by far the simplest way to stop agents from running simultaneously is to put them in the same database. I will very often create a special database that only contains agents and log documents generated by the agents. The agents can open any database, so it really doesn't matter where they are.
I also led a project once in which we built our own control mechanism for agents which was a combination of giulio and spookycoder's ideas. Only one 'master' agent was scheduled, and it read the control document to decide which agent should run next. Let's say we have agents A, B and C. The master runs A, which immediately updates the control document to say "I am running", then it updates fields with its progress information as it goes along, and finally when it is done it updates the control document with either "B",The next time the master runs, it looks at the control document. If the progress information shows that A has finished, the master will see that it is B's turn to run. Of course, A might realize that B has no work to do, so it might have written "C" instead, in which case the master will run C. The master also has the option to re-run A if the progress information shows that it did not finish the job.

Related

Multithreading operation in JSP

I am trying to build something, which requires multithreading functionality. The desired work was not done using javascript i.e. Web-Workers.
So I changed focus from javascript to JSP. Now I want to call one method which will execute series of some queries, and at the same time I want to show the affected table rows on other hand. And when first process done with it's execution, I want to stop other process also. My work is done but statically. Now I want to share some resource between this two threads. So that when first thread done with it's execution, I will set some value to that resource(variable,flag), and check that resource in another thread. Is it possible to access variable of one thread in another while it running.
Thanks
JavaScript in a browser is per design not capable of multithreading. You can simulate it a little bit when using setTimeout or setInterval methods.
But, as with the introduction of HTML5, there are now so called WebWorkers available. They run completely separate, spawn a real OS thread, do not have access the DOM but can interact with your UI application e.g. via events.

Java - How can I ensure I run a single instance of a process in a clustered environment

I have a jvm process that wakes a thread every X minutes.
If a condition is true -> it starts a job (JobA).
Another jvm process does almost the same but if the condition is true -
it throws a message to a message broker which triggers the job in another server (JobB).
Now, to avoid SPOF problem I want to add another instance of this machine in my cloud.
But than I want ensure I run a single instance of a JobA each time.
What are my options?
There are a number of patterns to solve this common problem. You need to choose based on your exact situation and depending on which factor has more weight in your case (performance, correctness, fail-tolerance, misfires allowed or not, etc). The two solution-groups are:
The "Quartz" way: you can use a JDBCStore from the Quartz library which (partially) was designed for this very reason. It allows multiple nodes to communicate, and share state and workload between each other. This solution gives you a probably perfect solution at the cost of some extra coding and setting up a shared DB (9 tables I think) between the nodes.
Alternatively your nodes can take care of the distribution itself: locking on a resource (single record in a DB for example) can be enough to decide who is in charge for that iteration of the execution. Sharing previous states however will require a bit more work.

Stopping a previous search without using multithreading Java?

I have a webpage that allows the user to enter a search criteria. Upon submission of the search form using the get method, a controller class reads in the search parameters, sets them as request attributes, then directs back to the page, which then calls a java class that has database connections and sql queries. The question I have is this: when the user decides to perform a new search while the current search is still not finished, is there a way to terminate the current search on the server before starting the new one.
You really didn't gave many information here. Especially you didn't write how do you connects to database. If you are using JDBC, you can cancel executing query with Statement.cancel(). Also you should hold information about current running query somewhere in session.
You need to interrupt() the thread that is doing the search and -admitted that the search Thread is doing some Thread.sleep() in between of performing the operations (eventually you should add those) - the thread will be interrupted by an InterruptedException that you should handle to break the search processing.
Still, you need to save the Thread.currentThread() somewhere (i.e. in the session) in order to retrieve a reference by the second one.
It's not trivial, and it's not very clean; since you need to put some interruption points in your search logic (i.e. the Thread.sleep() I mentioned before) and handle the InterruptedException properly.
For sure, the easier way is to ignore that the previous thread is still running and perform a new search.

applicability of mutli threading to a specific scenario in a java program

I am confused about the applicability of multi threading in general...
I am creating an application which executes some code which has been saved in xml format. The work is to use apache http client and retrieve some data from websites...More than 1 website can be visited by one block of code in xml...
Now I want that if 2 users have created their own respective codes and saved them in XML, then each user's 'job' (ie block of code in xml format) runs in a separate thread.
I have with me code to execute one user's code...Now I want that multiple persons' code can be run in parallel. But I have some doubts--
(1) The Apache HTTP client provides a way of multithreaded communication, currently I am simply using the default HTTP client- this same client can be made to visit multiple websites, one after the other- as per code block in xml. Am I correct in thinking that I do not need to change my code so that it uses the recommended multithreaded communication?
(2) I am thinking of creating a servlet that when invoked, executes one block of xml code. So to execute 2 blocks of code as given by 2 different users, I will have to invoke this servlet twice. I am going to deploy this application using Amazon Elastic Beanstalk, so what I am confused about is, do I need to use multi threading at all in my program? Can I not simply invoke the existing code (which is used to execute one block of code at a time) from the servlet? And I do want to keep processing of the different blocks of XML code separate from each other, so I dont think I should use multi threading here.. Am I correct in my assumption?
Running it one after the other as per your 1st option will not be considered 'concurrent' .
Coming to the servlet method , the way you describe it will work concurrently , but you also need to think about how many users concurrently ? Since for each user , there would be a separate request , there would be some network latency involved for multiple calls. You need to think about all these factors before going ahead with this option
Since you have the code for one user's job , you can define a thread class which has userid as an attribute. In the run() method call the code for a particular user's job.
Now create two threads and set the appropriate userid for each thread and spawn them off.
If the number of users are more , you can look at using Java's Thread Pool Executor .
Since you are going to use a servlet container then it's going to manage multithreading for you. Every servlet request will be executed in a different thread. In that scenario one servlet call would execute on block of code from provided XML in a single threaded manner. If there are several sites declared per block of code they would be visited serially. Other user in the same time may call the same server with other block of code running in parallel with the first one.

How to share data between scheduled jobs

I am writing a scheduler which grabs XML data and inserts into MySQL DB - simple isn't. But the problem or the logic that I am trying to find is here. NOTE: I want to execute this in windows environment in future it might be configured for other platforms.
Scheduler should run on every 5 mins.
This script should fetch condition/configuration on what to parse and collect the data-fields from XML and these conditions are available from MySQL table.
This table also defines a delay in which this script should check for the difference in the XML fields & delay.
This script does both, one is running for every 5 mins to collect XML and check the difference in the table (MySQL) for every said delay.
This script then reads the XML data-fields and parses it, then collects only those data-fields that is defined from the above MySQL table.
The collected data will be inserted into MySQL DB only when there is change in the state and this state is defined from MySQL table.
Feedback/Suggestions:
Due to the delay, I am not sure how should I store the configuration in the script which will be shared between each schedules.
Is there anyway to use static variable in the code to store this data? Which will be shared b/w different jobs? or different schedules?
Basically, how should I implement this? A better approach in terms of performance.
Thanks for your time.
UPDATE:
One of the suggestion is to use Java Code as a windows service (?) we could have some common data shared between different jobs? - does it make sense?
Reference:
Java Service Wrapper
Concurensy is the answer, try creating Thread pool or Executor servises, and stop certain threads for 5min , you coud even use Synchronization if few threads will be working with the same resource.
Remember not always the more threads use the faster you will finish your job f.e. 3 threads- 2 min
5threads-6 min
*Read tutorial about threads
*create fe simple threads with wait for 5 min
*read some tutorials about thread pool/synchnizations and sharing resourses (script part)
*test to find the most optimal way

Categories