Show / Hide Table of Contents

    Petabridge.Cmd Clients

    Petabridge.Cmd offers two types of clients to consumers of the software:

    • The pbm command line interface (CLI) - which has detailed installation and usage instructions and
    • Programmatic clients which can be invoked via C# or F# against an active PetabridgeCmd host installation.

    pbm CLI

    Rather than reproduce a lengthy document on how to work with the pbm CLI here, we have a dedicated piece of documentation for it here: pbm installation and usage instructions.

    IPbmClient Programmatic Client

    In some cases you may want to be able to invoke Petabridge.Cmd programmatically. As of Petabridge.Cmd 1.0+ we now support the ability to do this:

    1. In-process, running inside the same process as the PetabridgeCmd host and
    2. From a remote process, using the same TCP port that the PetabridgeCmd host uses to accept incoming connection requests.

    In both instances, you will create a handle that allows you to interact with Petabridge.Cmd that implements the IPbmClient interface and uses Akka.Streams Source<CommandResponse> to give you a stream of responses you can consume programmatically.

    Creating In-Process IPbmClient

    To create an in-process IPbmClient, we must first start the Petabridge.Cmd host normally:

    // create a Petabridge.Cmd host from our ActorSystem
    var pbmHost = PetabridgeCmd.Get(Sys);
    
    // start the host
    pbmHost.Start();
    

    If we want to create an "in-process" client, meaning one that runs in-memory inside the same process as the host, we just call the PetabridgeCmd.StartClient method - which will asynchronously return an IPbmClient instance for us to use:

    // create a client
    IPbmClient client = await pbmHost.StartLocalClient();
    
    // generate some logs that will show up instead the stream
    foreach (var i in Enumerable.Range(1, 10))
    {
        Log.Info("{0}", i);
    }
    
    // invoke a "log peek" command, just like you would on CLI
    CommandSession session = await client.ExecuteTextCommandAsync("log peek");
    
    // grab a hold of the Akka.Streams materializer from ActorSystem
    var materializer = Sys.Materializer();
    
    // pipe the Akka.Streams Source<CommandResponse> to a Sink<CommandResponse>
    // in this case, we're just going to send everything to a TestActor.
    // 
    // This Akka.Streams "graph" can be materialized into a Task, which will
    // complete once the stream is marked as complete by the Petabridge.Cmd host.
    var completionTask = session.Stream.RunForeach(rsp =>
    {
        TestActor.Tell(rsp);
    }, materializer);
    
    // and we can validate that the TestActor received at least one CommandResponse
    var response = ExpectMsg<CommandResponse>();
    
    // a client can also cancel the stream using the KillSwitch included
    // inside the CommandSession object
    session.KillSwitch.Shutdown();
    
    // once either of those two events occur, the Task returned earlier
    // will be complete
    await completionTask;
    

    From here we can invoke a log tail command and receive a CommandSession object in response. The CommandSession contains two important handles for us:

    1. A Source<CommandResponse> - an Akka.Streams source that we can use to consume all of the replies sent from a command invocation. Some commands will stream replies indefinitely, i.e. cluster tail, log tail, and others. Other commands will send back a finite number of responses and terminate on their own.
    2. A UniqueKillSwitch - an Akka.Streams handle that the client can use to terminate the response stream even in the server isn't finished yet.
    Important

    Each IPbmClient can run multiple, concurrent commands interactively with a single PetabridgeCmd host - this is a recent addition made as part of the Petabridge.Cmd 1.0 release.

    Create Remote Process IPbmClient

    Running a remote IPbmClient looks almost exactly the same as running an in-process client. The difference is: we have to pass in an EndPoint that the client will use to contact the PetabridgeCmd host over the network. This process will use the exact same port used by the pbm CLI - see the "host configuration" section for more details on how this works.

    // create a Petabridge.Cmd host from our ActorSystem
    // host is configured to run on port 11555 via HOCON
    var pbmHost = PetabridgeCmd.Get(Sys);
    
    // start the host
    pbmHost.Start();
    

    Our host is running on its own ActorSystem, bound to port 11555 via its HOCON configuration. We are going to create a second ActorSystem in a separate process and remotely connect to it on that port with a remote IPbmClient.

    // create client ActorSystem
    using ActorSystem clientSystem = ActorSystem.Create("ClientSystem");
    
    // grab copy of the PetabridgeCmdClient extension (Petabridge.Cmd.Common NuGet package)
    var clientExt = PetabridgeCmdClient.Get(clientSystem);
    
    // create IpEndPoint or DnsEndPoint for contacting remote host
    // either one of these would work
    var ip = new IPEndPoint(IPAddress.Loopback, 11555);
    var dns = new DnsEndPoint("localhost", 11555);
    
    // start a new IPbmClient attached to one of these EndPoints
    // by default this operation will time out in 5 seconds.
    // you can extend that by passing in a custom CancellationToken
    IPbmClient remoteClient = await clientExt.StartRemoteClient(ip);
    
    Note

    The PetabridgeCmdClient class can be found inside the Petabridge.Cmd.Common NuGet package - and that's the only NuGet package you need to install in order to create a remote IPbmClient instance.

    Once we've connected to our remote PetabridgeCmd, running our IPbmClient is identical to how we work with our in-process client:

    
    // generate some logs that will show up instead the stream
    foreach (var i in Enumerable.Range(1, 10))
    {
        Log.Info("{0}", i);
    }
    
    // invoke a "log peek" command, just like you would on CLI
    CommandSession session = await remoteClient.ExecuteTextCommandAsync("log peek");
    
    // grab a hold of the Akka.Streams materializer from ActorSystem
    var materializer = Sys.Materializer();
    
    // pipe the Akka.Streams Source<CommandResponse> to a Sink<CommandResponse>
    // in this case, we're just going to send everything to a TestActor.
    // 
    // This Akka.Streams "graph" can be materialized into a Task, which will
    // complete once the stream is marked as complete by the Petabridge.Cmd host.
    var completionTask = session.Stream.RunForeach(rsp =>
    {
        TestActor.Tell(rsp);
    }, materializer);
    
    // and we can validate that the TestActor received at least one CommandResponse
    var response = ExpectMsg<CommandResponse>();
    
    // a client can also cancel the stream using the KillSwitch included
    // inside the CommandSession object
    session.KillSwitch.Shutdown();
    
    // once either of those two events occur, the Task returned earlier
    // will be complete
    await completionTask;
    

    Network Issues

    In the event that the remote server disconnects from the client, the IPbmClient.IsAvailable property will return false and all of the Akka.Streams graphs connected to Source<CommandRepsonse>s associated with each CommandSession for that client will all be completed immediately and you will receive no further messages from the server.

    You will need to recreate a new IPbmClient instance if you wish to reconnect to the server and resume interacting with it.

    Back to top Generated by DocFX