use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class JCacheCacher method set.
@Override
public Promise set(String key, Tree value, int ttl) {
try {
int pos = partitionPosition(key, true);
// Prefix is the name of the partition / region (eg.
// "user" from the "user.name" cache key)
String prefix = key.substring(0, pos);
javax.cache.Cache<String, byte[]> partition;
writeLock.lock();
try {
partition = partitions.get(prefix);
if (partition == null) {
partition = cacheManager.getCache(prefix, String.class, byte[].class);
if (partition == null) {
// Find partition-specific config
Configuration<String, byte[]> cfg = cacheConfigurations.get(prefix);
if (cfg == null) {
// Use default config
cfg = defaultConfiguration;
}
// Create new cache
partition = cacheManager.createCache(prefix, cfg);
}
partitions.put(prefix, partition);
}
} finally {
writeLock.unlock();
}
if (value == null) {
partition.remove(key);
} else {
Tree root = new CheckedTree(Collections.singletonMap(CONTENT, value.asObject()));
byte[] bytes = serializer.write(root);
partition.put(key.substring(pos + 1), bytes);
}
} catch (Throwable cause) {
logger.warn("Unable to write data to JCache!", cause);
}
return Promise.resolve();
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class DefaultEventbus method addListeners.
// --- ADD REMOTE LISTENER ---
@Override
public void addListeners(Tree config) {
Tree events = config.get("events");
if (events != null && events.isMap()) {
String nodeID = Objects.requireNonNull(config.get("nodeID", (String) null));
String serviceName = Objects.requireNonNull(config.get("name", (String) null));
writeLock.lock();
try {
for (Tree listenerConfig : events) {
String subscribe = listenerConfig.get("name", "");
String group = listenerConfig.get("group", serviceName);
// Register remote listener
RemoteListenerEndpoint endpoint = new RemoteListenerEndpoint(transporter, nodeID, serviceName, group, subscribe);
// Get or create group map
HashMap<String, Strategy<ListenerEndpoint>> groups = listeners.get(subscribe);
if (groups == null) {
groups = new HashMap<String, Strategy<ListenerEndpoint>>();
listeners.put(subscribe, groups);
}
// Get or create strategy
Strategy<ListenerEndpoint> listenerStrategy = groups.get(group);
if (listenerStrategy == null) {
listenerStrategy = strategy.create();
groups.put(group, listenerStrategy);
}
listenerStrategy.addEndpoint(endpoint);
}
} finally {
// Clear caches
emitterCache.clear();
broadcasterCache.clear();
localBroadcasterCache.clear();
// Unlock reader threads
writeLock.unlock();
}
}
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class DefaultCircuitBreaker method callWithBreaker.
// --- CALL SERVICE WITH BREAKER FUNCTION ---
protected Promise callWithBreaker(String name, Tree params, CallOptions.Options opts, int remaining, Context parent) {
EndpointKey endpointKey = null;
ErrorCounter errorCounter = null;
try {
// Get the first recommended Endpoint and Error Counter
String targetID = opts == null ? null : opts.nodeID;
ActionEndpoint action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
String nodeID = action.getNodeID();
endpointKey = new EndpointKey(nodeID, name);
errorCounter = errorCounters.get(endpointKey);
// Check availability of the Endpoint (if endpoint isn't targetted)
if (targetID == null) {
LinkedHashSet<String> nodeIDs = new LinkedHashSet<>(maxSameNodes * 2);
int sameNodeCounter = 0;
long now;
if (errorCounter == null) {
now = 0;
} else {
now = System.currentTimeMillis();
}
for (int i = 0; i < maxTries; i++) {
if (errorCounter == null || errorCounter.isAvailable(now)) {
// Endpoint is available
break;
}
// Store nodeID
if (!nodeIDs.add(nodeID)) {
sameNodeCounter++;
if (sameNodeCounter >= maxSameNodes) {
// The "maxSameNodes" limit is reached
break;
}
}
// Try to choose another endpoint
action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
nodeID = action.getNodeID();
endpointKey = new EndpointKey(nodeID, name);
errorCounter = errorCounters.get(endpointKey);
}
}
// Create new Context
Context ctx = contextFactory.create(name, params, opts, parent);
// Invoke Endpoint
final ErrorCounter currentCounter = errorCounter;
final EndpointKey currentKey = endpointKey;
return Promise.resolve(action.handler(ctx)).then(rsp -> {
// Reset error counter
if (currentCounter != null) {
currentCounter.reset();
}
// Return response
return rsp;
}).catchError(cause -> {
// Increment error counter
increment(currentCounter, currentKey, cause, System.currentTimeMillis());
// Return with error
if (remaining < 1) {
return cause;
}
// Retry
return retryWithBreaker(cause, name, params, opts, remaining, parent);
});
} catch (Throwable cause) {
// Increment error counter
increment(errorCounter, endpointKey, cause, System.currentTimeMillis());
// Reject
if (remaining < 1) {
return Promise.reject(cause);
}
// Retry
return retryWithBreaker(cause, name, params, opts, remaining, parent);
}
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class Promise method all.
/**
* Returns a new Promise that is completed when all of the given Promise
* complete. If any of the given Promise complete exceptionally, then the
* returned Promise also does so, with a Promise holding this exception as
* its cause.
*
* @param promises
* array of Promises
*
* @return a new Promise that is completed when all of the given Promises
* complete
*/
public static final Promise all(Promise... promises) {
if (promises == null || promises.length == 0) {
return Promise.resolve();
}
@SuppressWarnings("unchecked") CompletableFuture<Tree>[] futures = new CompletableFuture[promises.length];
for (int i = 0; i < promises.length; i++) {
futures[i] = promises[i].future;
}
CompletableFuture<Void> all = CompletableFuture.allOf(futures);
return new Promise((r) -> {
all.whenComplete((Void, error) -> {
try {
if (error != null) {
r.reject(error);
return;
}
Tree array = new Tree().putList("array");
for (int i = 0; i < futures.length; i++) {
array.addObject(futures[i].get());
}
r.resolve(array);
} catch (Throwable cause) {
r.reject(cause);
}
});
});
}
use of io.datatree.Tree in project moleculer-java by moleculer-java.
the class RedisCacher method get.
// --- CACHE METHODS ---
@Override
public Promise get(String key) {
if (status.get() == STATUS_CONNECTED) {
try {
return client.get(key).then(in -> {
if (in != null) {
byte[] source = in.asBytes();
if (source != null) {
try {
Tree root = serializer.read(source);
Tree content = root.get(CONTENT);
if (content != null) {
return content;
}
return root;
} catch (Exception cause) {
logger.warn("Unable to deserialize cached data!", cause);
}
}
}
return Promise.resolve();
});
} catch (Exception cause) {
logger.warn("Unable to get data from Redis!", cause);
}
}
return Promise.resolve();
}
Aggregations