Corda RPC PoolBoy ¶
PoolBoy is an RPC connection pool with support for multiple Corda nodes.
Note this is an early release. It is highly unstable but provided in hope it can be useful. Contributions are welcome.
Installation¶
Add PoolBoy to your Cordapp’s Gradle dependencies:
dependencies{ // PoolBoy dependency compile("com.github.manosbatsis.corda.rpc.poolboy:corda-rpc-poolboy:$poolboy_version") // Corda dependencies etc. // ... }
Configuration¶
To use PoolBoy you will have to implement a RpcConfigurationService
.
The service provides RPC pool and connection configuration.
Implementations can be “fixed” or fully dynamic, e.g. based on
a properties file or database connection etc. respectively.
A future release will provide a sample, properties-based implementation. In the meantime you can find an example in Corbeans’ default
RpcConfigurationService.
The main configuration items provided by such a service are as follows:
getRpcPoolParams()
: APoolParams
instance, in each turn specifies:rpcClientsMode
: AnRpcClientsMode
value to control theCordaRPCClient
creation strategy, one ofSHARED
,POOLED
,DEDICATED
. Default isSHARED
.rpcClientPool
: The commons-pool2 keyed configuration to use ifrpcClientsMode
is set toPOOLED
, equivalent to aGenericKeyedObjectPoolConfig
.rpcOpsPool
: The commons-pool2 keyed configuration to use forNodeRpcConnection
instances - those start and wrap aCordaRPCOps
getRpcNodeParams(String)
: Provides the RPC connection configuration (i.e.NodeParams
) corresponding to the given node key per your configuration implementation, e.g. X500 name, application.properties key, database primary key etc. Note that the implementor is solely responsible for any caching.getGracefulReconnect(NodeParams)
: Override to change theGracefulReconnect
implementation to use whenNodeParams.disableGracefulReconnect
isfalse
.getCustomSerializers(List<String>)
: Custom serializer types found in the configured cordapp packages. Override to bypass classpath scanning and improve search discovery performance.buildPoolKey(String)
: Builds aPoolKey
for the given node name. Override to customisePoolKey.externalTrace
andPoolKey.impersonatedActor
, i.e. the equivalent parameters passed toCordaRPCClient.start()
Sample Usage¶
Using a full PoolBoy
:
// Create the PoolBoy instance val poolBoy = PoolBoy(myRpcConfigurationService) // Obtain a pool key for the target node val poolKey = myRpcConfigurationService.buildPoolKey(nodeName) // Do something with the CordaRPCOps // for the given node name poolBoy.withConnection(poolKey){ // e.g. start a flow it.proxy.startFlow(MyFlow::class.java, foo, bar, baz) }
Using a PoolBoyConnection
, i.e. a pooled connection
handle to a target node directly:
// Create the PoolBoy instance val poolBoy = PoolBoy(myRpcConfigurationService) // Obtain a pool key for the target node val poolKey = myRpcConfigurationService.buildPoolKey(nodeName) // Get a pool-able connection handle val pbCconn: PoolBoyConnection = poolBoy.forKey(poolKey) // Do something with the CordaRPCOps // for the target node pbCconn.withConnection { // e.g. start a flow it.proxy.startFlow(MyFlow::class.java, foo, bar, baz) }
Both PoolBoy
and PoolBoyConnection
have borrowConnection()
and returnConnection()
methods, but it’s highly discouraged; you’d
better know what you’re doing if you use them. The withConnection
approach is preferred.