use of info.xiancloud.core.distribution.service_discovery.UnitInstance in project xian by happyyangyuan.
the class UnitRouter method loadBalancedInstance.
public UnitInstance loadBalancedInstance(String unitFullName) throws UnitOfflineException, UnitUndefinedException {
UnitInstance instance = localInstance(unitFullName);
if (instance != null)
return instance;
newestDefinition(unitFullName);
/* do not delete this remark
here is for old virtual dao unit, not used any more.
if (unitFullName.startsWith(Constant.SYSTEM_DAO_GROUP_NAME.concat("."))) {
List<UnitInstance> mappedInstances = allInstances(unitFullName);
instance = mappedInstances.get(new Random().nextInt(mappedInstances.size()));
} else
*/
if (UnitDiscovery.singleton != null)
instance = UnitDiscovery.singleton.lb(unitFullName);
else {
// service discovery(zk) is optional plugin, we shouldn't depend on it.
// Service discovery is disabled currently, use local single node mode.
}
if (instance == null)
throw new UnitOfflineException(unitFullName);
return instance;
}
use of info.xiancloud.core.distribution.service_discovery.UnitInstance in project xian by happyyangyuan.
the class BroadcastSender method asyncSend.
@Override
protected void asyncSend() throws UnitOfflineException, UnitUndefinedException {
List<UnitInstance> list = UnitRouter.singleton.allInstances(Unit.fullName(unitRequest.getContext().getGroup(), unitRequest.getContext().getUnit()));
UnitMeta.Broadcast broadcast = list.get(0).getPayload().getMeta().getBroadcast();
final CountDownLatch latch = new CountDownLatch(list.size());
Collection<Object> piledUpOutput = new ConcurrentLinkedQueue<>();
final NotifyHandler tmpHandler = new NotifyHandler() {
protected void handle(UnitResponse output) {
if (!broadcast.isSuccessDataOnly()) {
piledUpOutput.add(output);
} else if (output.succeeded()) {
piledUpOutput.add(output.getData());
}
latch.countDown();
}
};
for (UnitInstance unitInstance : list) {
if (unitInstance.getNodeId().equals(LocalNodeManager.LOCAL_NODE_ID)) {
// we must not share the same unitRequest object while sending request concurrently.
UnitRequest clonedUnitRequest = CloneUtil.cloneBean(unitRequest, UnitRequest.class);
/*clonedUnitRequest.getContext().setDestinationNodeId(unitInstance.getNodeId()); no need */
new RoutedLocalAsyncSender(clonedUnitRequest, tmpHandler).send();
} else {
LOG.debug("In order not to share the same unit request object,we clone a new request");
UnitRequest clonedRequest = CloneUtil.cloneBean(unitRequest, UnitRequest.class);
clonedRequest.getContext().setDestinationNodeId(unitInstance.getNodeId());
LocalNodeManager.send(clonedRequest, tmpHandler);
}
}
if (broadcast.isAsync()) {
callback.callback(UnitResponse.success());
} else {
try {
if (!latch.await(broadcast.getTimeoutInMilli(), TimeUnit.MILLISECONDS)) {
LOG.error(new TimeoutException());
callback.callback(UnitResponse.error(Group.CODE_TIME_OUT, piledUpOutput, "Time out while waiting for all the units to response, the data is only part of the result. "));
} else {
callback.callback(UnitResponse.success(piledUpOutput));
}
} catch (InterruptedException e) {
callback.callback(UnitResponse.exception(e));
}
}
}
use of info.xiancloud.core.distribution.service_discovery.UnitInstance in project xian by happyyangyuan.
the class ReceiveAndBroadcast method execute.
@Override
public UnitResponse execute(UnitRequest msg) {
if (msg.getContext().isRouted()) {
return execute0(msg);
} else {
List<UnitInstance> list = new ArrayList<>();
String application = msg.get("application", String.class);
List<UnitInstance> unitInstances;
try {
unitInstances = UnitRouter.singleton.allInstances(Unit.fullName(getGroupName(), getUnitName()));
} catch (UnitOfflineException | UnitUndefinedException e) {
throw new RuntimeException(e);
}
if (StringUtil.isEmpty(application) || ALL.equals(application)) {
list.addAll(unitInstances);
} else {
for (UnitInstance clientInfo : unitInstances) {
if (clientInfo.getName().equals(msg.getString("application"))) {
list.add(clientInfo);
}
}
}
CountDownLatch latch = new CountDownLatch(list.size());
List<Object> piledUpOutput = new ArrayList<>();
for (UnitInstance clientInfo : list) {
LocalNodeManager.send(new UnitRequest().setContext(RequestContext.create().setGroup(getGroupName()).setUnit(getUnitName()).setDestinationNodeId(clientInfo.getNodeId())), new NotifyHandler() {
protected void handle(UnitResponse unitResponse) {
LOG.info("对" + clientInfo.getNodeId() + "执行" + getName() + "操作完毕");
if (!successDataOnly()) {
piledUpOutput.add(unitResponse);
} else if (unitResponse.succeeded()) {
piledUpOutput.add(unitResponse.getData());
}
latch.countDown();
}
});
}
if (async()) {
return UnitResponse.success();
} else {
try {
latch.await(timeoutInMilli(), TimeUnit.MILLISECONDS);
return UnitResponse.success(piledUpOutput);
} catch (InterruptedException e) {
return UnitResponse.exception(e);
}
}
}
}
use of info.xiancloud.core.distribution.service_discovery.UnitInstance in project xian by happyyangyuan.
the class UnitRouter method allInstances.
/**
* @return 返回包含指定服务的在线的客户端列表;
* 注意:这里不再对结果做了排序,如果是由于一致性哈希算法的需要,则 Let the code which uses constant hash do the sorting。
*/
public List<UnitInstance> allInstances(String fullUnitName) throws UnitOfflineException, UnitUndefinedException {
// for teasing.
newestDefinition(fullUnitName);
List<UnitInstance> instances;
if (UnitDiscovery.singleton != null)
instances = UnitDiscovery.singleton.all(fullUnitName);
else {
// service discovery(zk) is optional plugin, we shouldn't depend on it.
// Service discovery is disabled currently, use local single node mode.
instances = new ArrayList<>();
instances.add(localInstance(fullUnitName));
}
if (instances.isEmpty())
throw new UnitOfflineException(fullUnitName);
/*instances.sort(Comparator.comparing(UnitInstance::getNodeId));
* Let the code which uses constant hash do the sorting*/
return instances;
}
use of info.xiancloud.core.distribution.service_discovery.UnitInstance in project xian by happyyangyuan.
the class DaoUnitInstanceFilter method filter.
/**
* 过滤并保序,返回的顺序与application.properties配置的优先级顺序一致
*
* @deprecated mapped dao applications are no longer configured in the application.properties,
* using this filter will cause a unit not available exception.
*/
public List<UnitInstance> filter(Collection<UnitInstance> instances) {
List<UnitInstance> filtered = new ArrayList<>();
for (String dependentApplication : EnvUtil.getDependentApplications()) {
for (UnitInstance instance : instances) {
String application = NodeIdBean.parse(instance.getNodeId()).getApplication();
if (Objects.equals(application, EnvUtil.getApplication())) {
LOG.debug("优先考虑本地部署的dao unit,所以第一个添加进结果集");
filtered.add(instance);
} else if (Objects.equals(dependentApplication, application)) {
filtered.add(instance);
}
}
}
return filtered;
}
Aggregations