Writing RADOS Object Class Handlers in Lua
TweetThis post describes the API of the Lua object class handler system. In a previous post I provided some motivation for the project, and provided a description of the Lua object class error handling design. Another helpful resource is the Lua script used for internal unit testing that has working examples of the entire API.
Lua Object Class Structure
A Lua object class is an arbitrary Lua script containing at least one exported function handler that serves as a named entry point. By building up a collection of handlers, new and interesting interfaces to objects can be constructed and dynamically loaded into a running RADOS cluster. The basic structure is shown in the following code snippet:
In the above Lua script any number of functions and modules can be used to
support the behavior exported by the functions handler1
and handler2
. A
client can remotely execute any registered function and provide an arbitrary
input, and receive an arbitrary output. Attempting to call an unregistered
handler results in a error.
Logging and Tracing
An object class can write into the OSD log to record debugging information
using the log
function. The function takes any number of arguments which are
converted into strings and separated by spaces in the final output. If the
first argument is numeric then it is interpreted as a log-level. If no
log-level is specified a default log-level is used.
Logging can also be used to trace execution to aid in debugging. Any message
logged using the log
function will also be recorded in an ordered list and
returned to the client after execution. A client can print the list to view
the order of execution, analogous to using printf
statements for debugging.
Handler Registration
Object classes written in Lua may have many functions, only a subset of which
represent entry points to the functionality provided by the script. In order
to be able to call a function defined in a Lua object class, the function must
first be exported by registering it. This is done using the register
function. The following code snippet illustrates how this works.
In the above example cls.register(thehandler)
exports the function
thehandler
, making it available for clients to access. A client that
attempts to call the helper
function (an unregistered function), will
receive a return value of -ENOTSUPP
.
Metadata and Life Cycle
Use the stat
function to retrieve object size and modification time
information.
An object is created using the create
function which takes a boolean
parameter specifying exclusivity semantics. If true
is passed to create
and the object already exists then -ENOENT
is returned.
An object is deleted using the remove
function.
Object Payload I/O
The payload data of an object can be read from and written to using the read
and write
functions. Each function takes an offset and length parameter.
Indexing
A key/value store supporting range queries (based on Google's LevelDB) can be
accessed using the map_set_val
and map_get_val
functions. A key can be any
string and a value is a standard blob of any size.
Note: there are additional functions for interacting with the indexing service that are not reflected in the Lua bindings. While we covered the major components, we are expanding the interface as needed. If you need, please ask!