mirror of
https://github.com/corda/corda.git
synced 2025-03-14 00:06:45 +00:00
Merge pull request #903 from corda/merges/may-31-19-04
Merges: May 31 at 19:04
This commit is contained in:
commit
4f6b50dd8d
@ -24,21 +24,17 @@ Network Map Service
|
||||
|
||||
Supporting the messaging layer is a network map service, which is responsible for tracking public nodes on the network.
|
||||
|
||||
Nodes have an internal component, the network map cache, which contains a copy of the network map (which is just a
|
||||
document). When a node starts up its cache fetches a copy of the full network map, and requests to be notified of
|
||||
changes. The node then registers itself with the network map service, and the service notifies subscribers that a new
|
||||
node has joined the network. Nodes do not automatically deregister themselves, so (for example) nodes going offline
|
||||
briefly for maintenance are retained in the network map, and messages for them will be queued, minimising disruption.
|
||||
Nodes have an internal component, the network map cache, which contains a copy of the network map (which is backed up in the database
|
||||
to persist that information across the restarts in case the network map server is down). When a node starts up its cache
|
||||
fetches a copy of the full network map (from the server or from filesystem for development mode). After that it polls on
|
||||
regular time interval for network map and applies any related changes locally.
|
||||
Nodes do not automatically deregister themselves, so (for example) nodes going offline briefly for maintenance are retained
|
||||
in the network map, and messages for them will be queued, minimising disruption.
|
||||
|
||||
Nodes submit signed changes to the map service, which then forwards update notifications on to nodes which have
|
||||
requested to be notified of changes.
|
||||
|
||||
The network map currently supports:
|
||||
|
||||
* Looking up nodes by service
|
||||
* Looking up node for a party
|
||||
* Suggesting a node providing a specific service, based on suitability for a contract and parties, for example suggesting
|
||||
an appropriate interest rates oracle for an interest rate swap contract. Currently no recommendation logic is in place.
|
||||
Additionally, on every restart and on daily basis nodes submit signed `NodeInfo`s to the map service. When network map gets
|
||||
signed, these changes are distributed as new network data. `NodeInfo` republishing is treated as a heartbeat from the node,
|
||||
based on that network map service is able to figure out which nodes can be considered as stale and removed from the network
|
||||
map document after `eventHorizon` time.
|
||||
|
||||
Message queues
|
||||
--------------
|
||||
|
@ -191,3 +191,19 @@ Then node can be started as usual. At some point in time, nodes will gradually j
|
||||
information on business relations with operators. Private networks are not separate networks, nodes are still part of bigger
|
||||
compatibility zone, only hidden. We reuse all the infrastructure of the compatibility zone like notaries, permissioning service,
|
||||
so the interoperability between nodes is kept.
|
||||
|
||||
Cleaning the network map cache
|
||||
------------------------------
|
||||
|
||||
Sometimes it may happen that the node ends up with an inconsistent view of the network. This can occur due to changes in deployment
|
||||
leading to stale data in the database, different data distribution time and mistakes in configuration. For these unlikely
|
||||
events both RPC method and command line option for clearing local network map cache database exist. To use them
|
||||
you either need to run from the command line:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
java -jar corda.jar --clear-network-map-cache
|
||||
|
||||
or call RPC method `clearNetworkMapCache` (it can be invoked through the node's shell as `run clearNetworkMapCache`, for more information on
|
||||
how to log into node's shell see :doc:`shell`). As we are testing and hardening the implementation this step shouldn't be required.
|
||||
After cleaning the cache, network map data is restored on the next poll from the server or filesystem.
|
||||
|
@ -364,6 +364,10 @@ class SingleThreadedStateMachineManager(
|
||||
null
|
||||
}
|
||||
externalEventMutex.withLock {
|
||||
// Remove any sessions the old flow has.
|
||||
for (sessionId in getFlowSessionIds(currentState.checkpoint)) {
|
||||
sessionToFlow.remove(sessionId)
|
||||
}
|
||||
if (flow != null) addAndStartFlow(flowId, flow)
|
||||
// Deliver all the external events from the old flow instance.
|
||||
val unprocessedExternalEvents = mutableListOf<ExternalEvent>()
|
||||
|
@ -46,7 +46,7 @@ public class FlowShellCommand extends InteractiveShellCommand {
|
||||
@Usage("The class name of the flow to run, or an unambiguous substring") @Argument String name,
|
||||
@Usage("The data to pass as input") @Argument(unquote = false) List<String> input
|
||||
) {
|
||||
logger.info("Executing command \"flow start {} {}\",", name, input.stream().collect(joining(" ")));
|
||||
logger.info("Executing command \"flow start {} {}\",", name, (input != null) ? input.stream().collect(joining(" ")) : "<no arguments>");
|
||||
startFlow(name, input, out, ops(), ansiProgressRenderer(), objectMapper());
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class RunShellCommand extends InteractiveShellCommand {
|
||||
)
|
||||
@Usage("runs a method from the CordaRPCOps interface on the node.")
|
||||
public Object main(InvocationContext<Map> context, @Usage("The command to run") @Argument(unquote = false) List<String> command) {
|
||||
logger.info("Executing command \"run {}\",", command.stream().collect(joining(" ")));
|
||||
logger.info("Executing command \"run {}\",", (command != null) ? command.stream().collect(joining(" ")) : "<no arguments>");
|
||||
StringToMethodCallParser<CordaRPCOps> parser = new StringToMethodCallParser<>(CordaRPCOps.class, objectMapper());
|
||||
|
||||
if (command == null) {
|
||||
|
@ -31,7 +31,7 @@ public class StartShellCommand extends InteractiveShellCommand {
|
||||
public void main(@Usage("The class name of the flow to run, or an unambiguous substring") @Argument String name,
|
||||
@Usage("The data to pass as input") @Argument(unquote = false) List<String> input) {
|
||||
|
||||
logger.info("Executing command \"start {} {}\",", name, input.stream().collect(joining(" ")));
|
||||
logger.info("Executing command \"start {} {}\",", name, (input != null) ? input.stream().collect(joining(" ")) : "<no arguments>");
|
||||
ANSIProgressRenderer ansiProgressRenderer = ansiProgressRenderer();
|
||||
FlowShellCommand.startFlow(name, input, out, ops(), ansiProgressRenderer != null ? ansiProgressRenderer : new CRaSHANSIProgressRenderer(out), objectMapper());
|
||||
}
|
||||
|
@ -291,6 +291,7 @@ object InteractiveShell {
|
||||
while (!Thread.currentThread().isInterrupted) {
|
||||
try {
|
||||
latch.await()
|
||||
break
|
||||
} catch (e: InterruptedException) {
|
||||
try {
|
||||
rpcOps.killFlow(stateObservable.id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user