Reputation: 1
We have a web application in Java which calls progress procedures. Progress 4gl version is 10.x and is on AIX.
Requirement is to implement the following functionality: Suppose that a progress procedure is called by the web application. This makes an appserver transaction to run. While the transaction is processing, if the user closes the browser window the appserver process needs to be identified and should be killed using its process id. Killing of process can be implemented by invoking a shell script. How to identify the appserver process id for a web application session which is about to be closed?
Upvotes: 0
Views: 1535
Reputation: 8011
You have two good answers from both Tom and Tim. I think you need to rethink your architecture.
But that doesn't answer the question about getting the PID. Assuming that you run some kind of connection to an Progress AppServer, that AppServer is running a .p-program and in that program you could do:
FIND FIRST _MyConnection NO-LOCK.
/* You might not want to DISPLAY but rather do something else: */
DISPLAY _MyConnection._MyConn-Pid.
You could also do this in the OS. Assuming you have run the proenv-script so you have your environment set up you can do:
wtbman -name asXXX -query
(Replace asXXX with the name of your appserver - default is asbroker1).
Output is something like this:
OpenEdge Release 11.3.1 as of Fri Sep 13 19:00:23 EDT 2013
Connecting to Progress AdminServer using rmi://localhost:xxxx/Chimera (8280)
Searching for asXXX (8288)
Connecting to asXXX (8276)
Incorrect utility to use for asXXX (15827)
Broker Name : asXXX
Operating Mode : State-reset
Broker Status : ACTIVE
Broker Port : YYYY
Broker PID : ZZZZ
Active Servers : 2
Busy Servers : 0
Locked Servers : 0
Available Servers : 2
Active Clients (now, peak) : (0, 2)
Client Queue Depth (cur, max) : (0, 2)
Total Requests : 26322
Rq Wait (max, avg) : (18079 ms, 25 ms)
Rq Duration (max, avg) : (18079 ms, 25 ms)
PID State Port nRq nRcvd nSent Started Last Change
16319 AVAILABLE ZZZZZ 001447 001447 001447 Aug 8, 2014 11:50 Aug 14, 2014 13:20
16320 BUSY ZZZZZ 001385 001385 001385 Aug 8, 2014 11:50 Aug 14, 2014 13:10
Look at the list of pids. 16319 is AVAILABLE and 16320 is busy and has been for 10 minutes (if the time is 13:20 right now). That tells us that PID 16320 most likely is the hanging procedure.
Now you can do:
asbman -name asxxx -agentdetail 16320
That will give you more information like PROPATH, Stack trace and connected databases. Very helpful when looking for problems.
Upvotes: 0
Reputation: 14020
So the real issue is that you have long running tasks that users abandon and retry out of impatience (and possibly due to lack of feedback on the progress of the task)?
You haven't provided any details about your "web application in Java" so I don't really know what you are doing or how it relates to the Progress app server sessions.
In order for the web application to kill a process running remotely it will need to have some sort of reference to that remote process. It sounds like you are currently calling the remote process synchronously and waiting for a response. The first thing that you need to do is to call the remote process asynchronously (Progress does support asynchronous app server calls. That might be one starting point. But that depends on what "web application in Java" means.)
If you can somehow call the process asynchronously then you should obtain the PID (or some other unique identifier that can be used to xref the process) when you initiate it. That could then be used when you pop-up your confirmation alert-box to properly feed your "kill" command.
If you cannot figure out how to make an asynchronous app server call the crude way of emulating such things using a synchronous call is to marshall the request (and response) via a db table:
Insert a record describing the request, provide all necessary parameters and context to start the request independently and then return a request id to the caller.
The caller then loops -- pause for a period and check the status of the request. This should be a very simple call that just reads the request record from the db to pull its status.
On the remote side one or more batch processes are looping reading the request table looking for new records. When they find one they launch a process to execute the request. You can get fancy here with all sorts of controls and load balancing stuff or you can keep it simple and easy.
The process executing the request updates the status record as appropriate so that the web browser client can see what is going on. (step #2)
When the request is finished the result is fed back to the client -- possibly via a db table or maybe as a new page. That depends on the application. The basic idea is that when step #2 notices the status is "complete" it then does whatever is appropriate to fecth the result.
If the client decides to kill a request it should have received enough information in step #1 to pass that reference to the server so that the server can act on it. Usually you would want to update the status of the request record to "killed" (or whatever) and then either allow the sub process to notice that and terminate itself or use OS level tools to execute an actual "kill".
BTW -- if you appropriately organize the "context and parameters" portion of this you might be able to recognize and eliminate duplicate requests or at least cache the answers.
Upvotes: 0
Reputation: 3251
If the appserver process takes long enough that this is a concern, then you're doing something wrong - typically round-trip calls to an appserver should be so short that a closing a browser in the meantime wouldn't matter.
Second, if you're running state-free, there's no way to know which appserver agent a call is running as the last call could've been routed to any of a number of agents, and there's no handshaking back to the caller as to which one that is.
As such, the only reasonable way to do what you're looking for is to
Upvotes: 0