use of org.apache.ignite.services.Service in project ignite by apache.
the class GridServiceProxy method invokeMethod.
/**
* Invoek the method.
*
* @param mtd Method.
* @param args Arugments.
* @return Result.
*/
@SuppressWarnings("BusyWait")
public Object invokeMethod(final Method mtd, final Object[] args) {
if (U.isHashCodeMethod(mtd))
return System.identityHashCode(proxy);
else if (U.isEqualsMethod(mtd))
return proxy == args[0];
else if (U.isToStringMethod(mtd))
return GridServiceProxy.class.getSimpleName() + " [name=" + name + ", sticky=" + sticky + ']';
ctx.gateway().readLock();
try {
final long startTime = U.currentTimeMillis();
while (true) {
ClusterNode node = null;
try {
node = nodeForService(name, sticky);
if (node == null)
throw new IgniteException("Failed to find deployed service: " + name);
// If service is deployed locally, then execute locally.
if (node.isLocal()) {
ServiceContextImpl svcCtx = ctx.service().serviceContext(name);
if (svcCtx != null) {
Service svc = svcCtx.service();
if (svc != null)
return mtd.invoke(svc, args);
}
} else {
if (node.version().compareTo(SVC_POOL_SINCE_VER) >= 0)
ctx.task().setThreadContext(TC_IO_POLICY, GridIoPolicy.SERVICE_POOL);
// Execute service remotely.
return ctx.closure().callAsyncNoFailover(GridClosureCallMode.BROADCAST, new ServiceProxyCallable(mtd.getName(), name, mtd.getParameterTypes(), args), Collections.singleton(node), false, waitTimeout, true).get();
}
} catch (GridServiceNotFoundException | ClusterTopologyCheckedException e) {
if (log.isDebugEnabled())
log.debug("Service was not found or topology changed (will retry): " + e.getMessage());
} catch (RuntimeException | Error e) {
throw e;
} catch (IgniteCheckedException e) {
throw U.convertException(e);
} catch (Exception e) {
throw new IgniteException(e);
}
// If we are here, that means that service was not found
// or topology was changed. In this case, we erase the
// previous sticky node and try again.
rmtNode.compareAndSet(node, null);
// Add sleep between retries to avoid busy-wait loops.
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IgniteException(e);
}
if (waitTimeout > 0 && U.currentTimeMillis() - startTime >= waitTimeout)
throw new IgniteException("Service acquire timeout was reached, stopping. [timeout=" + waitTimeout + "]");
}
} finally {
ctx.gateway().readUnlock();
}
}
use of org.apache.ignite.services.Service in project gridgain by gridgain.
the class GridServiceProcessor method onKernalStop.
/**
* {@inheritDoc}
*/
@Override
public void onKernalStop(boolean cancel) {
if (ctx.isDaemon())
return;
GridSpinBusyLock busyLock = this.busyLock;
// Will not release it.
if (busyLock != null) {
busyLock.block();
this.busyLock = null;
}
startLatch.countDown();
U.shutdownNow(GridServiceProcessor.class, depExe, log);
if (!ctx.clientNode())
ctx.event().removeDiscoveryEventListener(topLsnr);
Collection<ServiceContextImpl> ctxs = new ArrayList<>();
synchronized (locSvcs) {
for (Collection<ServiceContextImpl> ctxs0 : locSvcs.values()) ctxs.addAll(ctxs0);
locSvcs.clear();
}
for (ServiceContextImpl ctx : ctxs) {
ctx.setCancelled(true);
Service svc = ctx.service();
if (svc != null)
try {
svc.cancel(ctx);
} catch (Throwable e) {
log.error("Failed to cancel service (ignoring) [name=" + ctx.name() + ", execId=" + ctx.executionId() + ']', e);
if (e instanceof Error)
throw e;
}
ctx.executor().shutdownNow();
}
for (ServiceContextImpl ctx : ctxs) {
try {
if (log.isInfoEnabled() && !ctxs.isEmpty())
log.info("Shutting down distributed service [name=" + ctx.name() + ", execId8=" + U.id8(ctx.executionId()) + ']');
ctx.executor().awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
U.error(log, "Got interrupted while waiting for service to shutdown (will continue stopping node): " + ctx.name());
}
}
Exception err = new IgniteCheckedException("Operation has been cancelled (node is stopping).");
cancelFutures(depFuts, err);
cancelFutures(undepFuts, err);
if (log.isDebugEnabled())
log.debug("Stopped service processor.");
}
use of org.apache.ignite.services.Service in project gridgain by gridgain.
the class GridServiceProcessor method service.
/**
* {@inheritDoc}
*/
@Override
public <T> T service(String name) {
ctx.security().authorize(name, SecurityPermission.SERVICE_INVOKE);
Collection<ServiceContextImpl> ctxs;
synchronized (locSvcs) {
ctxs = locSvcs.get(name);
}
if (ctxs == null)
return null;
synchronized (ctxs) {
if (ctxs.isEmpty())
return null;
for (ServiceContextImpl ctx : ctxs) {
Service svc = ctx.service();
if (svc != null)
return (T) svc;
}
return null;
}
}
use of org.apache.ignite.services.Service in project gridgain by gridgain.
the class GridServiceProxy method invokeMethod.
/**
* Invoek the method.
*
* @param mtd Method.
* @param args Arugments.
* @return Result.
*/
@SuppressWarnings("BusyWait")
public Object invokeMethod(final Method mtd, final Object[] args) throws Throwable {
if (U.isHashCodeMethod(mtd))
return System.identityHashCode(proxy);
else if (U.isEqualsMethod(mtd))
return proxy == args[0];
else if (U.isToStringMethod(mtd))
return GridServiceProxy.class.getSimpleName() + " [name=" + name + ", sticky=" + sticky + ']';
ctx.gateway().readLock();
try {
final long startTime = U.currentTimeMillis();
while (true) {
ClusterNode node = null;
try {
node = nodeForService(name, sticky);
if (node == null)
throw new IgniteException("Failed to find deployed service: " + name);
// If service is deployed locally, then execute locally.
if (node.isLocal()) {
ServiceContextImpl svcCtx = ctx.service().serviceContext(name);
if (svcCtx != null) {
Service svc = svcCtx.service();
if (svc != null)
return callServiceLocally(svc, mtd, args);
}
} else {
ctx.task().setThreadContext(TC_IO_POLICY, GridIoPolicy.SERVICE_POOL);
// Execute service remotely.
return ctx.closure().callAsyncNoFailover(GridClosureCallMode.BROADCAST, new ServiceProxyCallable(methodName(mtd), name, mtd.getParameterTypes(), args), Collections.singleton(node), false, waitTimeout, true).get();
}
} catch (InvocationTargetException e) {
// For local services rethrow original exception.
throw e.getTargetException();
} catch (RuntimeException | Error e) {
throw e;
} catch (IgniteCheckedException e) {
// Check if ignorable exceptions are in the cause chain.
Throwable ignorableCause = X.cause(e, ClusterTopologyCheckedException.class);
if (ignorableCause == null && ctx.service() instanceof GridServiceProcessor)
ignorableCause = X.cause(e, GridServiceNotFoundException.class);
if (ignorableCause != null) {
if (log.isDebugEnabled())
log.debug("Service was not found or topology changed (will retry): " + ignorableCause.getMessage());
} else {
// Rethrow original service method exception so that calling user code can handle it correctly.
ServiceProxyException svcProxyE = X.cause(e, ServiceProxyException.class);
if (svcProxyE != null)
throw svcProxyE.getCause();
throw U.convertException(e);
}
} catch (Exception e) {
throw new IgniteException(e);
}
// If we are here, that means that service was not found
// or topology was changed. In this case, we erase the
// previous sticky node and try again.
rmtNode.compareAndSet(node, null);
// Add sleep between retries to avoid busy-wait loops.
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IgniteException(e);
}
if (waitTimeout > 0 && U.currentTimeMillis() - startTime >= waitTimeout)
throw new IgniteException("Service acquire timeout was reached, stopping. [timeout=" + waitTimeout + "]");
}
} finally {
ctx.gateway().readUnlock();
}
}
use of org.apache.ignite.services.Service in project gridgain by gridgain.
the class IgniteServiceProcessor method cancel.
/**
* Perform cancelation on given service context.
*
* @param ctx Service context.
*/
private void cancel(ServiceContextImpl ctx) {
// Flip cancelled flag.
ctx.setCancelled(true);
// Notify service about cancellation.
Service srvc = ctx.service();
if (srvc != null) {
try {
srvc.cancel(ctx);
} catch (Throwable e) {
U.error(log, "Failed to cancel service (ignoring) [name=" + ctx.name() + ", execId=" + ctx.executionId() + ']', e);
if (e instanceof Error)
throw e;
} finally {
try {
this.ctx.resource().cleanup(srvc);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to clean up service (will ignore): " + ctx.name(), e);
}
}
}
// Close out executor thread for the service.
// This will cause the thread to be interrupted.
ctx.executor().shutdownNow();
if (log.isInfoEnabled()) {
log.info("Cancelled service instance [name=" + ctx.name() + ", execId=" + ctx.executionId() + ']');
}
}
Aggregations