Ask Reuben
DVM_AVAILABLE
What is the DVM_AVAILABLE timeout?
The Genero Application Server (GAS) architecture has a number of parts with the proxy, dispatcher, and DVM. In the configuration there are a number of timeout configurations that control what happens if something happens and the proxy, dispatcher, and DVM can no longer communicate with each other. Applications and Services both have different set of timeouts but they both have a timeout that I want to talk about, that is DVM_AVAILABLE.
The DVM_AVAILABLE dictates how long a proxy process will wait after it has started a DVM (*) for the DVM (program) to respond back that it has started. This adds some protection in the event that if the program cannot start, the web application client or web service client does not wait for ever. The default value is 10 seconds.
The key thing to note is what is it that tells the proxy that the program has started …
- With a Web Application, that is the first time the runtime gives control back to the user i.e. the first MENU, PROMPT, INPUT, CONSTRUCT, DISPLAY ARRAY, INPUT ARRAY, DIALOG statement, or ui.Interface.Refresh statement, as part of the Dynamic User Interface protocol.
- With a Web Service, that is the com.WebServiceEngine.start method.
We see two types of DVM_AVAILABLE being triggered. When there is a genuine error and the program fails to start, but the real head scratcher can occur when there is nothing inherently wrong with your application, it is just that it takes more than 10 seconds to start this one instance. With a Web Service this is then magnified by the Web Service invalidation feature and any further requests to that Web Service are denied.
When we look at these head scratchers with Web Services what we see is code that is roughly paraphrased as …
MAIN ... CALL init() -- includes a CONNECT statement ... CALL com.WebServiceEngine.start()
In conjunction with the Program Profiler we might see that the code between the MAIN and com.WebServiceEngine.start normally takes a number of seconds to execute. All it then takes is a small hiccup in the network and/or database and/or server load for 10 seconds to elapse between the MAIN and com.WebServiceEngine.start and then the DVM_AVAILABLE timeout is triggered.
A simple solution is to bump DVM_AVAILABLE upto 15 seconds but if there is a genuine error then it will take 15 seconds for the timeout to be triggered. The other solution is to review your code and minimise the distance between the MAIN and first UI interaction for a Web Application or the MAIN and com.WebServiceEngine.start for a Web Service.
For a Web Application that may involve putting a splash screen around your initialisation so that there is some UI whilst the initialisation is taking place e.g.
MAIN ... OPEN WINDOW splash WITH FORM "splash" CALL ui.Interface.Refresh() ... CALL init() -- includes CONNECT statement ... CLOSE WINDOW splash
For a Web Service that may involve moving your com.WebServiceEngine.start() up above any initialisation e.g.
MAIN CALL com.WebServiceEngine.start() CALL init() ....
… although this may have an impact on the statistics the proxy keeps for how long a web service takes to start and how long it takes to process requests.
The key is to minimise the chances of any interruption between the MAIN and the statement that effectively tells the proxy process that the fglrun program has started and is waiting for you to respond.
When analysing you should be aware of how can you tell DVM_AVAILABLE has been triggered.
With a Web Service you will see this in the VM log …
HTTPServerAsImpl::Error :connection failed WSServer::start :connection failed Program stopped at '????????.4gl', line number ???. FORMS statement error number -15515. No application server has been started at specified host.
… because what has happened, the program has taken more than DVM_AVAILABLE seconds to start. It has attempted to communicate with the application server (proxy) that it is ready to process web services, only the proxy process has given up listening after DVM_AVAILABLE seconds, and so the fglrun process thinks there is nothing waiting to listen to it.
In the proxy log you will have two entries DVM_AVAILABLE seconds apart. An entry that shows the proxy starting
10:56:54.003696 ... Proxy created.
and then DVM_AVAILABLE seconds later an entry showing that the program failed to connect , note the 10 second gap in the timestamps.
10:57:04.008648 1..."Start process" A DVM failed to connect to port ....
I am a great believer in once you have something running, break it in one place and note the output. So with your running programs and web services, add a SLEEP 15
(assuming DVM_AVAILABLE=10) between the MAIN
and the line of code that will communicate back with the proxy, observe what happens and what appears in the logs. Similarly add a WHENEVER ANY ERROR STOP DISPLAY 1/0
to force an error to occur and again observe what happens and what appears in the logs. File that away in your knowledge base so that if you see these appear in your logs, you can start looking at DVM_AVAILABLE and what happens when the Genero application or Genero web service starts.
(*) DVM stands for Dynamic Virtual Machine. It is probably one of those terms we assume you know as I can’t find a definition for it in current documentation. If you see DVM, you can read it as “the fglrun process/program/executable”