-
Notifications
You must be signed in to change notification settings - Fork 97
How To: Add a new command message in Arkouda
This article will walk through the basic steps of adding a new client <---> server command and message response to Arkouda. At its conclusion you should have a general idea of how to add new server functionality and wire its invocation into the python client.
Let's start with a basic scenario where a CarEntry was recently added to the server as a complex object. This means we have a stateful object persisted in memory over on the server that we can interact with in various ways. Let's assume our entry/object has
- Mileage - number of miles on the odometer
- Color
We will also assume the creation of our new CarEntry has already been implemented and we want to add a new command which changes/updates the Color of the car.
We have a number of pieces in play and a number of areas in the code where we will need to update.
In the python, client-side code we'll assume we have a cars.py with a class Car in it. Our job is to add a new function to this class which will set the color of the car entry stored on the server. Let's call this new function set_color(color:str)
class Car:
# ... initialization code etc.
def set_color(color:str):
pass
# Here is where we will need to add the code for sending the new color over to the serverIn general our current pattern (subject to change!) is that we have a module containing all of the code related to the handling & operations we would perform to our server side object. Depending on how complex the code is sometimes we break the module into separate components and sometimes we keep it contained in a single module. Our convention for naming modules related to commands and message passing is to name it after the object with the Msg suffix. In our case here we are going to call it CarMsg. (If you are adding functionality to an existing server object/class/entry look for a corresponding *Msg module.)
Let's assume we have a file which already exists in the Arkouda server code section named src/CarMsg.chpl. This is the file where we are going to add our new command and message response code.
module CarMsg {
proc setCarColorMsg(cmd:string, payload:string, st:borrowed SymTab): MsgTuple throws {
// This is the code we are going to add.
// We'll discuss the message signature after we understand more of the pieces
}
}Ok, we have modules and classes on both the client & server side code where we are going to write our new code, but we need to understand some of the other layers before we write our code. (NOTE: Some of the components we'll list here are a bit outside the scope of this how-to so we may not go into depth on each of the them.)
-
MultiTypeSymEntry.chpl- This is where the Symbol Entry definitions and types live. If you're implementing a new Complex entry on the server you will need to put it here. For our story we are assuming aCarEntryalready exists here. -
MultiTypeSymbolTable.chpl- Contains the code for our Symbol Table (SymTab) which holds the references to our named objects in memory. Generally there are convenience functions for retrieving our entry by name/id and casting it to the proper type; we will assume this already exists asgetCarEntry. -
CarMsg.chpl- This is where ourCarMsgmodule lives and where we plan to add our newsetCarColorMsg. -
CommandMap.chpl- This is the pseudo Dependency Injection piece introduce in our shift to a more modular, configurable build. This contains the code which makes it possible to bind our string command (i.e.setCarColorCmd) to the function executing our car color update. -
arkouda_server.chpl- This is the code which contains our main run-time loop. When we start an arkouda server process, this is the where the code execution begins and is where we route command strings to their respective functions stored in ourCommandMap. -
ServerModules.cfg- With our modular build process, this is where we configure which modules will be included. We will assume ourCarMsgmodule is already listed in this file. -
Message.chpl- This contains the definition of ourMsgTuplerecord which is the response object passed back to the client.
There are 2 flows of control we should keep in mind: 1. server startup and 2. command routing and processing
Our first flow of control is server start up which is how our command gets registered with the server. We will bind our string literal command name setCarColorCmd to our function CarMsg.setCarColorMsg