package org.simantics.r.scl; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.rosuda.REngine.Rserve.RConnection; import org.rosuda.REngine.Rserve.RserveException; import org.simantics.scl.runtime.function.Function; public class RSessionManager { static ConcurrentHashMap CONNECTIONS = new ConcurrentHashMap(); public static RSession getSession(String id) { // CONNECTIONS is ConcurrentHashMap so no synchronization is needed here return CONNECTIONS.get(id); } public static RSession createSession(RSessionConfiguration configuration) throws RserveException { synchronized(CONNECTIONS) { String id = UUID.randomUUID().toString(); return createSession(configuration, id); } } public static Object withConfiguration(RSessionConfiguration configuration, @SuppressWarnings("rawtypes") Function f) throws RserveException { RSession session = createSession(configuration); try { return session.syncExec(f); } catch (InterruptedException e) { throw new RuntimeException(e); } finally { session.close(); } } public static RSession getOrCreateSession(RSessionConfiguration configuration, String id) throws RserveException { synchronized(CONNECTIONS) { RSession session = getSession(id); if(session == null) return createSession(configuration, id); else return session; } } private static RSession createSession(RSessionConfiguration configuration, String id) throws RserveException { synchronized(CONNECTIONS) { RConnection connection = new RConnection(configuration.host, configuration.port); if(configuration.username != null && !configuration.username.isEmpty()) connection.login(configuration.username, configuration.password); RSession managedConnection = new RSession(connection, id); CONNECTIONS.put(id, managedConnection); return managedConnection; } } }