com.zeroc.IceInternal.FactoryACMMonitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ice Show documentation
Show all versions of ice Show documentation
Ice is a comprehensive RPC framework that helps you build distributed applications with minimal effort using familiar object-oriented idioms
//
// Copyright (c) ZeroC, Inc. All rights reserved.
//
package com.zeroc.IceInternal;
class FactoryACMMonitor implements ACMMonitor
{
static class Change
{
Change(com.zeroc.Ice.ConnectionI connection, boolean remove)
{
this.connection = connection;
this.remove = remove;
}
final com.zeroc.Ice.ConnectionI connection;
final boolean remove;
}
FactoryACMMonitor(Instance instance, ACMConfig config)
{
_instance = instance;
_config = config;
}
@SuppressWarnings("deprecation")
@Override
protected synchronized void
finalize()
throws Throwable
{
try
{
com.zeroc.IceUtilInternal.Assert.FinalizerAssert(_instance == null);
com.zeroc.IceUtilInternal.Assert.FinalizerAssert(_connections.isEmpty());
com.zeroc.IceUtilInternal.Assert.FinalizerAssert(_changes.isEmpty());
com.zeroc.IceUtilInternal.Assert.FinalizerAssert(_reapedConnections.isEmpty());
}
catch(java.lang.Exception ex)
{
}
finally
{
super.finalize();
}
}
synchronized void
destroy()
{
if(_instance == null)
{
//
// Ensure all the connections have been cleared, it's important to wait here
// to prevent the timer destruction in IceInternal::Instance::destroy.
//
while(!_connections.isEmpty())
{
try
{
wait();
}
catch(InterruptedException ex)
{
}
}
return;
}
if(!_connections.isEmpty())
{
//
// Cancel the scheduled timer task and schedule it again now to clear the
// connection set from the timer thread.
//
assert(_future != null);
_future.cancel(false);
_future = null;
_instance.timer().schedule(() -> { monitorConnections(); }, 0, java.util.concurrent.TimeUnit.MILLISECONDS);
}
_instance = null;
_changes.clear();
//
// Wait for the connection set to be cleared by the timer thread.
//
while(!_connections.isEmpty())
{
try
{
wait();
}
catch(InterruptedException ex)
{
}
}
}
@Override
public void
add(com.zeroc.Ice.ConnectionI connection)
{
if(_config.timeout == 0)
{
return;
}
synchronized(this)
{
assert(_instance != null);
if(_connections.isEmpty())
{
_connections.add(connection);
assert _future == null;
_future = _instance.timer().scheduleAtFixedRate(() -> { monitorConnections(); },
_config.timeout / 2,
_config.timeout / 2,
java.util.concurrent.TimeUnit.MILLISECONDS);
}
else
{
_changes.add(new Change(connection, false));
}
}
}
@Override
public void
remove(com.zeroc.Ice.ConnectionI connection)
{
if(_config.timeout == 0)
{
return;
}
synchronized(this)
{
assert(_instance != null);
_changes.add(new Change(connection, true));
}
}
@Override
public synchronized void
reap(com.zeroc.Ice.ConnectionI connection)
{
_reapedConnections.add(connection);
}
@Override
public synchronized ACMMonitor
acm(java.util.OptionalInt timeout, java.util.Optional close,
java.util.Optional heartbeat)
{
assert(_instance != null);
ACMConfig config = _config.clone();
if(timeout != null && timeout.isPresent())
{
config.timeout = timeout.getAsInt() * 1000; // To milliseconds
}
if(close != null && close.isPresent())
{
config.close = close.get();
}
if(heartbeat != null && heartbeat.isPresent())
{
config.heartbeat = heartbeat.get();
}
return new ConnectionACMMonitor(this, _instance.timer(), config);
}
@Override
public com.zeroc.Ice.ACM
getACM()
{
com.zeroc.Ice.ACM acm = new com.zeroc.Ice.ACM();
acm.timeout = _config.timeout / 1000;
acm.close = _config.close;
acm.heartbeat = _config.heartbeat;
return acm;
}
synchronized java.util.List
swapReapedConnections()
{
if(_reapedConnections.isEmpty())
{
return null;
}
java.util.List connections = _reapedConnections;
_reapedConnections = new java.util.ArrayList<>();
return connections;
}
private void
monitorConnections()
{
synchronized(this)
{
if(_instance == null)
{
_connections.clear();
notifyAll();
return;
}
for(Change change : _changes)
{
if(change.remove)
{
_connections.remove(change.connection);
}
else
{
_connections.add(change.connection);
}
}
_changes.clear();
if(_connections.isEmpty())
{
_future.cancel(false);
_future = null;
return;
}
}
//
// Monitor connections outside the thread synchronization, so
// that connections can be added or removed during monitoring.
//
long now = Time.currentMonotonicTimeMillis();
for(com.zeroc.Ice.ConnectionI connection : _connections)
{
try
{
connection.monitor(now, _config);
}
catch(Exception ex)
{
handleException(ex);
}
}
}
synchronized void
handleException(Exception ex)
{
if(_instance == null)
{
return;
}
_instance.initializationData().logger.error("exception in connection monitor:\n" + ex);
}
private Instance _instance;
final private ACMConfig _config;
private java.util.Set _connections = new java.util.HashSet<>();
private java.util.List _changes = new java.util.ArrayList<>();
private java.util.List _reapedConnections = new java.util.ArrayList<>();
private java.util.concurrent.Future> _future;
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy