PoolBoy is an RPC connection pool with support for multiple Corda nodes.
See complete documentation at https://manosbatsis.github.io/corda-rpc-poolboy
Note this is an early release. It is highly unstable but provided in hope it can be useful. Contributions are welcome.
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.
// ...
} 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(): APoolParamsinstance, in each turn specifies:rpcClientsMode: AnRpcClientsModevalue to control theCordaRPCClientcreation strategy, one ofSHARED,POOLED,DEDICATED. Default isSHARED.rpcClientPool: The commons-pool2 keyed configuration to use ifrpcClientsModeis set toPOOLED, equivalent to aGenericKeyedObjectPoolConfig.rpcOpsPool: The commons-pool2 keyed configuration to use forNodeRpcConnectioninstances - 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 theGracefulReconnectimplementation to use whenNodeParams.disableGracefulReconnectisfalse.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 aPoolKeyfor the given node name. Override to customisePoolKey.externalTraceandPoolKey.impersonatedActor, i.e. the equivalent parameters passed toCordaRPCClient.start()
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.