Project

General

Profile

Support #10389

Ending Web application does not free port

Added by Șerban Bursuc 12 months ago. Updated 11 months ago.

Status:
WIP
Priority:
Normal
Target version:
-
Start date:
Due date:
% Done:

50%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
version_resolved:
production:
No
env_name:
topics:

10389_no_available_ports.flv (1.91 MB) Șerban Bursuc, 08/08/2025 06:44 AM

directory.xml Magnifier (89.7 KB) Șerban Bursuc, 08/08/2025 08:03 AM

res-width2.p Magnifier (2.47 KB) Șerban Bursuc, 08/08/2025 08:03 AM

my-server.log.0 (63.1 KB) Șerban Bursuc, 08/08/2025 08:08 AM

History

#1 Updated by Șerban Bursuc 12 months ago

When making small testcases and ending the application with ESC the port allocated to the web client spawner is not freed. This prevents any relogin after closing the application and requires a server restart. This is very annoying and takes a lot of time when converting applications and testing them on the web client. This doesn't happen on customer applications for example when they are gracefully shut down (usually by logging out from the business code) but it happens when closing simple testcases or on customer application crashes. Does anybody know if there is a certain condition to correctly free the port, does it need settings in directory.xml or is this a bug? Or anything that could either forcefully deallocate the port, or create a new one to prevent this error?

Video showcasing the issue attached.

#2 Updated by Sergey Ivanovskiy 12 months ago

The video is not enough to make a guess what happens here. Please add directory.xml, test program to reproduce and logs.

#3 Updated by Șerban Bursuc 12 months ago

Sure, all attached.

I just figured out now that if I wait for the "websocket connection lost" message and then press ESC again I can gracefully exit the application.

Is there a way to configure how long you need to wait for the popup to appear?

#4 Updated by Sergey Ivanovskiy 12 months ago

Șerban, please note that your directory.xml has a remote debug option

          <node class="string" name="jvmArgs">

            <node-attribute name="value" value="-Xmx512m -Djava.awt.headless=true -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=2998,server=y,suspend=n"/>

          </node>

and in this case the dubug configuration profile is applied for web clients. So, the actual values are those that can be found in this log
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.util.Utils | ThreadName:qtp1636257629-87 | not available host:port localhost/127.0.0.1:7449.
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: delayBetweenTriesToConnect=5000
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: delayBetweenPingTries=1000
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: embWebServerMaxIdleTimeout=0
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: enableDebugLogging=true
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: maxIdleTime=1200000
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: maxLostPings=6
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: webSocketTimeout=1200000
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: pingPongInterval=1200000
25/08/08 15:07:39.591+0300 | WARNING | com.goldencode.p2j.main.WebClientBuilderParameters | ThreadName:qtp1636257629-87 | DEBUG MODE: watchdogTimeout=2400000

It seems that you experienced the ports shortage because watch dog timeout is 2400 seconds. These settings are needed to be able to set breakpoints and debug the code slowly while the web client continues to be alive.

#5 Updated by Sergey Ivanovskiy 12 months ago

But in your log there is this severe message

25/08/08 15:07:52.076+0300 |  SEVERE | com.goldencode.p2j.util.TransactionManager [TransactionManager.deferError] | ThreadName:Conversation [00000002:bogus], Session:00000002, ThreadId:00000005, User:bogus | <depth = 1; trans_level = -1; trans_label = null; rollback_scope = -1; rollback_label = null; rollback_pending = false; in_quit = false; retry_scope = -1; retry_label = null; ignore_err = false> [label = startup; type = UNKNOWN; full = false; trans_level = NO_TRANSACTION; external = true; top_level = true; loop = false; loop_protection = true; had_pause = true; endkey_retry = false; next_or_leave = leave; is_retry = false; needs_retry = false; FOR (aggressive) flushing = false; ilp_count = -1; pending_break = false; database_trigger = false; properties = ''; finally = none] Error processing finished; deferring throw until block/iteration completes
com.goldencode.p2j.util.EndConditionException: END-ERROR key function
    at com.goldencode.p2j.ui.chui.ThinClient.processCondition(ThinClient.java:23781)
    at com.goldencode.p2j.ui.chui.ThinClient.pause(ThinClient.java:10784)
    at com.goldencode.p2j.ui.chui.ThinClient.pauseBeforeEnd(ThinClient.java:19817)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:569)
    at com.goldencode.p2j.util.MethodInvoker.invoke(MethodInvoker.java:126)
    at com.goldencode.p2j.net.Dispatcher.processInbound(Dispatcher.java:808)
    at com.goldencode.p2j.net.Conversation.block(Conversation.java:418)
    at com.goldencode.p2j.net.Conversation.waitMessage(Conversation.java:344)
    at com.goldencode.p2j.net.Queue.transactImpl(Queue.java:1239)
    at com.goldencode.p2j.net.Queue.transact(Queue.java:687)
    at com.goldencode.p2j.net.BaseSession.transact(BaseSession.java:276)
    at com.goldencode.p2j.net.HighLevelObject.transact(HighLevelObject.java:221)
    at com.goldencode.p2j.net.RemoteObject$RemoteAccess.invokeCore(RemoteObject.java:1468)
    at com.goldencode.p2j.net.InvocationStub.invoke(InvocationStub.java:144)
    at jdk.proxy2/jdk.proxy2.$Proxy11.standardEntry(Unknown Source)
    at com.goldencode.p2j.main.ClientCore.start(ClientCore.java:476)
    at com.goldencode.p2j.main.ClientDriver.start(ClientDriver.java:287)
    at com.goldencode.p2j.main.CommonDriver.process(CommonDriver.java:522)
    at com.goldencode.p2j.main.ClientDriver.process(ClientDriver.java:171)
    at com.goldencode.p2j.main.ClientDriver.main(ClientDriver.java:330)
25/08/08 15:07:52.077+0300 |  SEVERE | com.goldencode.p2j.util.TransactionManager [TransactionManager.handleDeferredError] | ThreadName:Conversation [00000002:bogus], Session:00000002, ThreadId:00000005, User:bogus | <depth = 0; trans_level = -1; trans_label = null; rollback_scope = -1; rollback_label = null; rollback_pending = false; in_quit = false; retry_scope = -1; retry_label = null; ignore_err = false>  Throwing deferred error (END-ERROR key function)
25/08/08 15:07:52.455+0300 | WARNING | com.goldencode.p2j.security.SecurityContext | ThreadName:Reader [00000002:bogus], Session:00000002, ThreadId:00000006, User:bogus | SecurityContext.cleanupWorker did not complete properly - the following tokens are still in use: [com.goldencode.p2j.util.Utils$ContextContainer, com.goldencode.p2j.util.SessionUtils$1, com.goldencode.p2j.util.SessionUtils$2, com.goldencode.p2j.util.osresource.OSResourceManager$1]

#6 Updated by Șerban Bursuc 12 months ago

Sergey Ivanovskiy wrote:

But in your log there is this severe message
[...]

That's an exception generated from the ESC key to end the application. What should happen is that on ESC press the app should terminate, but I need to wait for the websocket connection popup to appear and then press ESC again to close it.

On Swing ESC + Spacebar terminates and closes a FWD client instantly.

Another weird discovery is that ESC + Spacebar works perfectly fine on Incognito for me. It's instant and I don't have to wait for any popup.

#7 Updated by Sergey Ivanovskiy 12 months ago

Șerban Bursuc wrote:

Sergey Ivanovskiy wrote:

But in your log there is this severe message
[...]

That's an exception generated from the ESC key to end the application. What should happen is that on ESC press the app should terminate, but I need to wait for the websocket connection popup to appear and then press ESC again to close it.

On Swing ESC + Spacebar terminates and closes a FWD client instantly.

Another weird discovery is that ESC + Spacebar works perfectly fine on Incognito for me. It's instant and I don't have to wait for any popup.

I think that there is the bug here but it is not clear why this key action affects web clients.

#8 Updated by Sergey Ivanovskiy 12 months ago

but I need to wait for the websocket connection popup to appear and then press ESC again to close it.

I guess it is not correct. The application should terminates the java web client the same as for the swing client.

#9 Updated by Șerban Bursuc 11 months ago

Pressing ESC twice should not cause the websocket connection lost message, same as holding ESC. This bug can be fixed to prevent waiting for the delayBetweenTriesToConnect timeout. It would be a good quality of life bug fix.

#10 Updated by Sergey Ivanovskiy 11 months ago

Șerban Bursuc wrote:

Pressing ESC twice should not cause the websocket connection lost message, same as holding ESC. This bug can be fixed to prevent waiting for the delayBetweenTriesToConnect timeout. It would be a good quality of life bug fix.

Please explain how it relates to the issue. The web client should act as the swing client and 4GL native application. delayBetweenTriesToConnect timeout should not be a solution for this issue.

#11 Updated by Șerban Bursuc 11 months ago

Sergey Ivanovskiy wrote:

Șerban Bursuc wrote:

Pressing ESC twice should not cause the websocket connection lost message, same as holding ESC. This bug can be fixed to prevent waiting for the delayBetweenTriesToConnect timeout. It would be a good quality of life bug fix.

Please explain how it relates to the issue. The web client should act as the swing client and 4GL native application. delayBetweenTriesToConnect timeout should not be a solution for this issue.

What I mean here is on a web client application ESC -> ESC (press twice) or just holding ESC should immediately quit the application. It doesn't like in OE. It hangs and you need to wait delayBetweenTriesToConnect time for the "websocket connection lost" popup to appear. Only then you can press another ESC to safely free the port.

Another bug (?) is like this:
  • The server hangs from a FWD bug or due to poor performance and you want to quit out.
  • If you refresh the page and try to login again, the client port is still in use.
  • You kill ServerDriver with a command like this: ps aux | grep ServerDriver | awk '{print $2}' | head -n 2 | xargs kill -9
  • Now you can login, but midway through the loading screen disappears and you get the "no ports available" error again.
  • You have to restart the server to be able to login again.

You should be able to at least kill the client thread and be able to relogin, or a page refresh should release the port. This wastes a lot of time in large projects when you are profiling for example, you sample for a few minutes but the scenario literally takes hours, so you want to close the client and relogin but you need to do a server restart.

#12 Updated by Șerban Bursuc 11 months ago

An easy example of a hanging application is #10087-19, this testcase on the web client hangs and there is no way to end it besides killing the server, logging in again, getting the ports error, and then killing the server again.

edit: not a good example

#13 Updated by Șerban Bursuc 11 months ago

The ESC issue is fixed by this change:

=== modified file 'src/com/goldencode/p2j/ui/chui/ThinClient.java'
--- old/src/com/goldencode/p2j/ui/chui/ThinClient.java    2025-07-28 08:11:21 +0000
+++ new/src/com/goldencode/p2j/ui/chui/ThinClient.java    2025-08-13 10:47:59 +0000
@@ -23860,7 +23860,7 @@
                                            lastKey);

       // END-ERROR action
-      if (action == Keyboard.KA_END_ERROR)
+      if (action == Keyboard.KA_END_ERROR && !inPause)
       {
          int effective = interactions;

Throwing an exception here results in the hanging state, but if no exception is thrown on the second ESC then the application ends gracefully.

#14 Updated by Greg Shah 11 months ago

  • Assignee set to Șerban Bursuc
  • reviewer Sergey Ivanovskiy added

#15 Updated by Greg Shah 11 months ago

  • % Done changed from 0 to 50
  • Status changed from New to Review

#16 Updated by Șerban Bursuc 11 months ago

  • Assignee changed from Șerban Bursuc to Eric Faulhaber
  • vendor_id deleted (GCD)

Sergey, the patch above isn't fully correct, but the idea stands, if we are in a pause caused by END-ERROR another ESC press should not throw a StopConditionException, it should be treated like any other key. So there are several ways to fix this bug.

#17 Updated by Șerban Bursuc 11 months ago

  • Assignee deleted (Eric Faulhaber)
  • vendor_id set to GCD

#18 Updated by Șerban Bursuc 11 months ago

  • Assignee set to Șerban Bursuc

#19 Updated by Sergey Ivanovskiy 11 months ago

  • Status changed from Review to WIP

OK, please create the task branch 10389a.

#20 Updated by Sergey Ivanovskiy 11 months ago

It seems that the similar issue was discussed in some task but I did not find where it was.

#21 Updated by Șerban Bursuc 11 months ago

I don't understand this try block:

11057.1.2   ca@gold |    
                    |          try
                    |          {
                    |             // honor the STOP, ENDKEY and END-ERROR actions
                    |             if (key != null)
                    |                processCondition(key.actionCode(), -1, true);
                    |          }
                    |          finally
                    |          {
                    |             // erase status message, only in ChUI
                    |             if (!noMessage && isChui())
                    |             {
                    |                wnd.window().status(null);
                    |             }
                    |    
                    |             if (isChui())
                    |             {
                    |                // hide messages
                    |                wnd.window().setMessageText(null, null);
                    |             }
                    |    

Why process the condition? Any key besides some modifier keys like CTRL and SHIFT end the application. It looks like we are deliberately trying to throw a StopConditionException here. I see #3100 with this change where there were some fixes to batch mode and app servers. Should this check not be done for GUI?

Also available in: Atom PDF