/** * Check if there are deferred follower callback notifications. * * @return true if there are deferred follower callback notifications * */ public boolean hasDeferredNotifications() { return callbackService.hasDeferredNotifications(); } }
/** * Starts state synchronization for expired callbacks (past expiration time and state is STARTED or EXPIRED). * The follower contract that launched it is notified of the synchronized state of the callback. */ public void synchronizeFollowerCallbacks() { int nodesCount = network.getNodesCount(); if (nodesCount < 2) return; Collection<CallbackRecord> callbackRecords = ledger.getFollowerCallbacksToResync(); if (callbackRecords.isEmpty()) return; startSynchronizeFollowerCallbacks(callbackRecords, nodesCount); }
/** * Initialize callback service on node and start synchronization thread. * * @param node is Universa node * @param config is node configuration * @param myInfo is node information * @param ledger is DB ledger * @param network is Universa network * @param nodeKey is public key of node * @param executorService is executor service from node to run synchronization */ public CallbackService(Node node, Config config, NodeInfo myInfo, Ledger ledger, Network network, PrivateKey nodeKey, ScheduledExecutorService executorService) { this.node = node; this.config = config; this.myInfo = myInfo; this.ledger = ledger; this.network = network; this.nodeKey = nodeKey; this.executorService = executorService; // start synchronization executorService.scheduleWithFixedDelay(() -> synchronizeFollowerCallbacks(), 60, config.getFollowerCallbackSynchronizationInterval().getSeconds(), TimeUnit.SECONDS); }
private synchronized void startSynchronizeFollowerCallbacks(Collection<CallbackRecord> callbackRecords, int nodesCount) { ZonedDateTime expiresAt = ZonedDateTime.now().plusSeconds(20); callbackRecords.forEach(r -> { if (!callbacksToSynchronize.containsKey(r.getId())) { // init record to synchronization r.setExpiresAt(expiresAt); r.setConsensusAndLimit(nodesCount); callbacksToSynchronize.put(r.getId(), r); // request callback state from all nodes network.broadcast(myInfo, new CallbackNotification(myInfo, r.getId(), CallbackNotification.CallbackNotificationType.GET_STATE, null)); } }); executorService.schedule(() -> endSynchronizeFollowerCallbacks(), 20, TimeUnit.SECONDS); }
/** * Notification handler. Checking type of notification and call needed obtainer. * */ private final void onNotification(Notification notification) { if (notification instanceof ParcelNotification) { obtainParcelCommonNotification((ParcelNotification) notification); } else if (notification instanceof ResyncNotification) { obtainResyncNotification((ResyncNotification) notification); } else if (notification instanceof ItemNotification) { obtainCommonNotification((ItemNotification) notification); } else if (notification instanceof CallbackNotification) { callbackService.obtainCallbackNotification((CallbackNotification) notification); } }
callbackService = new CallbackService(this, config, myInfo, ledger, network, nodeKey, lowPrioExecutorService);
callbackService.startCallbackProcessor(((ContractSubscription.ApprovedWithCallbackEvent) event).getNewRevision(), ItemState.APPROVED, this, (NMutableEnvironment) me); callbackService.startCallbackProcessor(((ContractSubscription.RevokedWithCallbackEvent) event).getRevokingItem(), ItemState.REVOKED, this, (NMutableEnvironment) me);
extraResult.set("onUpdateResult", ((NSmartContract) item).onUpdated(me)); lowPrioExecutorService.schedule(() -> callbackService.synchronizeFollowerCallbacks(me.getId()), 1, TimeUnit.SECONDS);
/** * Starts state synchronization for expired callbacks (past expiration time and state is STARTED or EXPIRED) for environment. * The follower contract that launched it is notified of the synchronized state of the callback. * * @param environmentId is callback processor */ public void synchronizeFollowerCallbacks(long environmentId) { int nodesCount = network.getNodesCount(); if (nodesCount < 2) return; Collection<CallbackRecord> callbackRecords = ledger.getFollowerCallbacksToResyncByEnvId(environmentId); if (callbackRecords.isEmpty()) return; startSynchronizeFollowerCallbacks(callbackRecords, nodesCount); }
newExtraResult.set("onUpdateResult", ((NSmartContract) newItem).onUpdated(me)); lowPrioExecutorService.schedule(() -> callbackService.synchronizeFollowerCallbacks(me.getId()), 1, TimeUnit.SECONDS);