After some further debugging I was able to workaround the
described problem by making the connection to the virtual machine
work regardless of the used hostname in the endpoint description.
I used some constant value for ENDPOINT_ID and used
RemoteConstants.ENDPOINT_CONNECTTARGET_ID to define the "real
network" target/host to connect to:
props.put(RemoteConstants.ENDPOINT_CONNECTTARGET_ID, "ecftcp://"
+ host + ":8889/server");
props.put(ENDPOINT_ID, "p4://server");
So no more hostname matching to identify the correct service on the
target machine.
But the original problem still remains unresolved ...
Bye, Peter
Am 18.09.2017 um 14:24 schrieb Peter
Hermsdorf:
Hi Scott,
thanks for your suggestion, but the described fix does not
seem to work. The returned container is always null and so
cannot be disconnected. This is caused by the importEndpoint of
the importReference being null.
This is what I'm doing:
1) register my remote service and a reconnect listener for that
service:
final ImportRegistration registration =
remoteServiceAdmin.importService(endpointDescription);
final ReconnectServiceAdminListener reconnectListener =
new ReconnectServiceAdminListener(remoteServiceAdmin,
containerManager,
registration, endpointDescription);
context.registerService(RemoteServiceAdminListener.class.getName(),
reconnectListener, null);
2) inside the ReconnectListener I basically try to re-import
the service when the registration/connection fails:
public class ReconnectServiceAdminListener implements
RemoteServiceAdminListener {
private static final Duration RECONNECT_DELAY =
Duration.ofSeconds(10);
private final ReconnectJob reconnectJob;
private final EndpointDescription endpointDescription;
private final RemoteServiceAdmin remoteServiceAdmin;
private ImportRegistration registration;
private final IContainerManager containerManager;
public ReconnectServiceAdminListener(final
RemoteServiceAdmin remoteServiceAdmin,
final IContainerManager containerManager, final
ImportRegistration registration,
final EndpointDescription endpointDescription) {
this.remoteServiceAdmin = remoteServiceAdmin;
this.containerManager = containerManager;
this.registration = registration;
this.endpointDescription = endpointDescription;
reconnectJob = new ReconnectJob();
if (registration.getException() != null) {
reconnectJob.schedule(RECONNECT_DELAY.toMillis());
}
}
@Override
public void remoteAdminEvent(final RemoteServiceAdminEvent
e) {
final
org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.RemoteServiceAdminEvent
event =
(org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.RemoteServiceAdminEvent)
e;
if
(event.getEndpointDescription().isSameService(endpointDescription))
{
switch (event.getType()) {
case
RemoteServiceAdminEvent.IMPORT_UNREGISTRATION:
case RemoteServiceAdminEvent.IMPORT_ERROR:
reconnectJob.schedule(RECONNECT_DELAY.toMillis());
break;
}
}
}
class ReconnectJob extends Job {
public ReconnectJob() {
super("ReconnectJob");
}
@Override
protected IStatus run(final IProgressMonitor monitor) {
final
org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.ImportRegistration
remoteServiceImportRegistration =
(org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.ImportRegistration)
registration;
final ID containerID =
remoteServiceImportRegistration.getContainerID();
final IContainer container =
containerManager.getContainer(containerID);
if (container != null) {
container.disconnect();
}
registration.close();
registration =
remoteServiceAdmin.importService(endpointDescription);
return Status.OK_STATUS;
}
}
}
The Thread count still increases with every run of the
ReconnectJob.
Any suggestions on how to solve this issue?
Thanks!
Bye Peter
Am 16.09.2017 um 05:03 schrieb Scott
Lewis:
Hi
Peter,
I'm assuming that you are using the generic provider.
I think you can do what you need to do by:
1) You can cast the ImportRegistration to
org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.ImportRegistration
2) Call
org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteServiceAdmin.ImportRegistration.getContainerID()
to get the container ID
3) Using the IContainerManager service (a singleton ecf service)
and the ID from 2 call: IContainer c =
containerManager.getContainer(id) to get the associated
container instance.
4) Call c.disconnect() to release the connection and associated
threads.
Scott
On 9/15/2017 7:27 AM, Peter Hermsdorf wrote:
Hi,
we encountered a problem while trying to import services
exported from a process running in a local VM (_not_ JVM). The
VM forwards the necessary port to the host machine.
As for the problem: RemoteAdminService#importService causes a
RemoteAdminServiceEvent.IMPORT_ERROR to be signalled and the
connections/threads opened due to the importService call do
not get closed, even though we call ImportRegistration#close()
on failed attempts. The latter does not happen, if there is no
one listening on the port at all. Since, we have code that
regularly calls importService again for services, that should
be, but are not currently imported (according to
RemoteAdminService#getImportedEndpoints), we slowly accumulate
more and more threads.
The tcp connection to the local VM seems to be successful, but
due to issues regarding requested hostname and actual hostname
ECF (correctly) does not "connect the services" (see https://dev.eclipse.org/mhonarc/lists//ecf-dev/msg07259.html
for a discussion of the "hostname problem - localhost !=
getCanonicalHostname()" in EndPointDescriptions; in this case
it is host::getCanonicalHostname() !=
VM::getCanonicalHostname())
So importService creates threads/connections, fails to import,
and even with a call to ImportRegistration#close() does not
clean up the threads/connections.
Any suggestions on how to solve this issue or more generally
handle this reconnect use-case are more than welcome!
Best regards,
Bye Peter
PS: we use the ecf generic provider on the latest ecf release
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or
unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/ecf-dev
_______________________________________________
ecf-dev mailing list
ecf-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or
unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/ecf-dev
|