Assuming that I set correct credentials and we do know how to set dfc preferences in runtime, what does code below print?
@Test public void test() throws Exception { int count = 0; try { DfPreferences preferences = DfPreferences.getInstance(); preferences.loadProperty(DfPreferences.DFC_SESSION_MAX_COUNT, 50); while (++count > 0) { IDfClientX clientX = new DfClientX(); IDfClient client = clientX.getLocalClient(); IDfSessionManager sessionManager = client.newSessionManager(); IDfLoginInfo loginInfo = clientX.getLoginInfo(); loginInfo.setUser("dmadmin"); loginInfo.setPassword("dmadmin"); sessionManager.setIdentity("DCTM_DEV", loginInfo); IDfSession session = sessionManager.getSession("DCTM_DEV"); } } finally { System.out.println("Session count: " + count); } }
Actually, the answer is obvious – that buggy code creates 50 sessions and fails:
Session count: 50 DfServiceException:: THREAD: main; MSG: [DM_API_E_NO_SESSION]error: "There are no more available sessions." ; ERRORCODE: 100; NEXT: null at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getConnectionFromPool(DocbaseConnectionManager.java:168) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getDocbaseConnection(DocbaseConnectionManager.java:94) at com.documentum.fc.client.impl.session.SessionFactory.newSession(SessionFactory.java:23) at com.documentum.fc.client.impl.session.PrincipalAwareSessionFactory.newSession(PrincipalAwareSessionFactory.java:44) at com.documentum.fc.client.impl.session.PooledSessionFactory.newSession(PooledSessionFactory.java:49) at com.documentum.fc.client.impl.session.SessionManager.getSessionFromFactory(SessionManager.java:134) at com.documentum.fc.client.impl.session.SessionManager.newSession(SessionManager.java:72) at com.documentum.fc.client.impl.session.SessionManager.getSession(SessionManager.java:191) at SessionDemo.test(SessionDemo.java:30)
Now, less obvious code:
@Test public void test() throws Exception { int count = 0; try { DfPreferences preferences = DfPreferences.getInstance(); preferences.loadProperty(DfPreferences.DFC_SESSION_MAX_COUNT, 50); preferences.loadProperty(DfPreferences.DFC_DIAGNOSTICS_RESOURCES_ENABLE, true); while (++count > 0) { IDfClientX clientX = new DfClientX(); IDfClient client = clientX.getLocalClient(); IDfSessionManager sessionManager = client.newSessionManager(); IDfLoginInfo loginInfo = clientX.getLoginInfo(); loginInfo.setUser("dmadmin"); loginInfo.setPassword("dmadmin"); sessionManager.setIdentity("DCTM_DEV", loginInfo); IDfSession session = sessionManager.getSession("DCTM_DEV"); } } finally { System.out.println("Session count: " + count); } }
the result is bit confusing – code creates more than 50 sessions and fails:
... 25586 [Resource Housekeeper] ERROR com.documentum.fc.client.impl.session.StrongSessionHandle$DisposableData - [DFC_SESSION_NOT_RELEASED] Unreleased session found during garbage collection, Session{id=29, iid=29, serial=1, docbase=DCTM_DEV, user=dmadmin, serversession=none} com.documentum.fc.impl.util.ThrowableStack: Stack when session was obtained at SessionDemo.test(SessionDemo.java:31) ... Session count: 94 DfServiceException:: THREAD: main; MSG: [DM_API_E_NO_SESSION]error: "There are no more available sessions." ; ERRORCODE: 100; NEXT: null at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getConnectionFromPool(DocbaseConnectionManager.java:168) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getDocbaseConnection(DocbaseConnectionManager.java:94) at com.documentum.fc.client.impl.session.SessionFactory.newSession(SessionFactory.java:23) at com.documentum.fc.client.impl.session.PrincipalAwareSessionFactory.newSession(PrincipalAwareSessionFactory.java:44) at com.documentum.fc.client.impl.session.PooledSessionFactory.newSession(PooledSessionFactory.java:49) at com.documentum.fc.client.impl.session.SessionManager.getSessionFromFactory(SessionManager.java:134) at com.documentum.fc.client.impl.session.SessionManager.newSession(SessionManager.java:72) at com.documentum.fc.client.impl.session.SessionManager.getSession(SessionManager.java:191) at SessionDemo.test(SessionDemo.java:31)
another code:
@Test public void test() throws Exception { int count = 0; try { DfPreferences preferences = DfPreferences.getInstance(); preferences.loadProperty(DfPreferences.DFC_SESSION_MAX_COUNT, 50); preferences.loadProperty(DfPreferences.DFC_DIAGNOSTICS_RESOURCES_ENABLE, true); while (++count > 0) { IDfClientX clientX = new DfClientX(); IDfClient client = clientX.getLocalClient(); IDfSessionManager sessionManager = client.newSessionManager(); IDfLoginInfo loginInfo = clientX.getLoginInfo(); loginInfo.setUser("dmadmin"); loginInfo.setPassword("dmadmin"); sessionManager.setIdentity("DCTM_DEV", loginInfo); IDfSession session = sessionManager.getSession("DCTM_DEV"); System.gc(); } } finally { System.out.println("Session count: " + count); } }
the result is weird – code prints a lot of diagnostics messages but does not fail:
... 115902 [Resource Housekeeper] ERROR com.documentum.fc.client.impl.session.StrongSessionHandle$DisposableData - [DFC_SESSION_NOT_RELEASED] Unreleased session found during garbage collection, Session{id=1, iid=1207, serial=1, docbase=DCTM_DEV, user=dmadmin, serversession=none} com.documentum.fc.impl.util.ThrowableStack: Stack when session was obtained at SessionDemo.test(SessionDemo.java:31) ...
and the last example:
@Test public void test() throws Exception { int count = 0; try { DfPreferences preferences = DfPreferences.getInstance(); preferences.loadProperty(DfPreferences.DFC_SESSION_MAX_COUNT, 50); preferences.loadProperty(DfPreferences.DFC_DIAGNOSTICS_RESOURCES_ENABLE, true); while (++count > 0) { IDfClientX clientX = new DfClientX(); IDfClient client = clientX.getLocalClient(); IDfSessionManager sessionManager = client.newSessionManager(); IDfLoginInfo loginInfo = clientX.getLoginInfo(); loginInfo.setUser("dmadmin"); loginInfo.setPassword("dmadmin"); sessionManager.setIdentity("DCTM_DEV", loginInfo); IDfSession session = sessionManager.getSession("DCTM_DEV"); session.beginTrans(); System.gc(); } } finally { System.out.println("Session count: " + count); } }
result is even more weird – code does not print diagnostic messages and fails:
4964 [Resource Housekeeper] ERROR com.documentum.fc.client.impl.connection.docbase.DocbaseConnection - Connection put back in pool with transaction active, Connection{id=1, docbase=DCTM_DEV, user=dmadmin, state=FREE} Session count: 50 DfServiceException:: THREAD: main; MSG: [DM_API_E_NO_SESSION]error: "There are no more available sessions." ; ERRORCODE: 100; NEXT: null at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getConnectionFromPool(DocbaseConnectionManager.java:168) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.getDocbaseConnection(DocbaseConnectionManager.java:94) at com.documentum.fc.client.impl.session.SessionFactory.newSession(SessionFactory.java:23) at com.documentum.fc.client.impl.session.PrincipalAwareSessionFactory.newSession(PrincipalAwareSessionFactory.java:44) at com.documentum.fc.client.impl.session.PooledSessionFactory.newSession(PooledSessionFactory.java:49) at com.documentum.fc.client.impl.session.SessionManager.getSessionFromFactory(SessionManager.java:134) at com.documentum.fc.client.impl.session.SessionManager.newSession(SessionManager.java:72) at com.documentum.fc.client.impl.session.SessionManager.getSession(SessionManager.java:191) at SessionDemo.test(SessionDemo.java:31)
Corresponding thread dump:
"Resource Housekeeper" #13 daemon prio=10 os_prio=31 tid=0x00007fb78c1bd800 nid=0x5703 in Object.wait() [0x0000700001452000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000006c0dc9828> (a com.documentum.fc.client.impl.connection.docbase.DocbaseConnection) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.waitForCorrectSharingContext(DocbaseConnection.java:820) - locked <0x00000006c0dc9828> (a com.documentum.fc.client.impl.connection.docbase.DocbaseConnection) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.evaluateRpc(DocbaseConnection.java:1108) - locked <0x00000006c0dc9828> (a com.documentum.fc.client.impl.connection.docbase.DocbaseConnection) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.applyForBool(DocbaseConnection.java:1198) - locked <0x00000006c0dc9828> (a com.documentum.fc.client.impl.connection.docbase.DocbaseConnection) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.apply(DocbaseConnection.java:1183) at com.documentum.fc.client.impl.docbase.DocbaseApi.endTrans(DocbaseApi.java:1757) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.cleanupFromUnexpectedTransactionState(DocbaseConnection.java:729) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnection.quiesce(DocbaseConnection.java:663) - locked <0x00000006c0dc9828> (a com.documentum.fc.client.impl.connection.docbase.DocbaseConnection) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.returnConnectionToPool(DocbaseConnectionManager.java:663) at com.documentum.fc.client.impl.connection.docbase.DocbaseConnectionManager.release(DocbaseConnectionManager.java:270) at com.documentum.fc.client.impl.session.Session.releaseConnection(Session.java:248) at com.documentum.fc.client.impl.session.PooledSessionFactory$SessionListener.onDisconnect(PooledSessionFactory.java:114) at com.documentum.fc.client.impl.session.Session.notifyListenersOfDisconnect(Session.java:395) at com.documentum.fc.client.impl.session.Session.disconnect(Session.java:312) at com.documentum.fc.client.impl.session.Session.decrementReferenceCount(Session.java:3687) at com.documentum.fc.client.impl.session.StrongSessionHandle$DisposableData.dispose(StrongSessionHandle.java:127) at com.documentum.fc.internal.reshousekeeper.ResourceHousekeeper$1$1.run(ResourceHousekeeper.java:52)
Try to explain results 🙂