On 9/19/2017 6:00 AM, Peter Hermsdorf
wrote:
Hi again,
the workaround described below does not work in all
circumstances.
The problem still seems to be that remote services can only be
successfully registered if the client uses the exact same
hostname for the endpoint ID as used by the server itself.
Otherwise the containerID's in
org.eclipse.ecf.remoteservice.RemoteServiceID.namespaceEquals(BaseID)
does not match and the service registration fails (I'm not sure
if there are additional other places where the hostname matters
while service import/export).
The problem for me is, that the "local" hostname where the
service is provided is not always the network visibly name the
clients need to use to connect to the server.
Is there a way to make the remote services work then the client
(service consumer) and the server (service provider) use
different hostnames for the server?
Hi Peter. I'm sorry I haven't been able to respond to this whole
thread as there are a number of things...e.g. the workaround you are
using, other possible work-arounds, etc. I've been very occupied
recently. But should we focus on this question specifically for
the moment?
It is possible to customize remote services in a number of ways and
so I'm pretty sure what you are asking for is possible. It might
mean creating a custom distribution provider (e.g. extending an
existing one), and/or some additional customization of the remote
services impl, but I think it's probably possible.
I will also go back to your original posting to understand your use
case but because my memory is limited, it might also be helpful if
you would review the behavior you would like to see for your
environment...e.g. what network interface(s) the server is listening
on, what externally-visible names (i.e. dns) names it has and how
that relates to the interface(s) and associated ip addresses, and
what you would like the clients to use in order to connect to that
server and import services.
Also maybe a short review on how you are doing export, discovery and
import (e.g. via direct calls to RemoteServiceAdmin, via
registerService, etc).
If you would prefer to not do this publicly I understand...please
just contact me at slewis at composent.com and we'll take things
offline.
Thanks,
Scott
I'm using ecf generic server.
Thanks for any hints!
Bye Peter
Am 18.09.2017 um 16:22 schrieb Peter
Hermsdorf:
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
|