NAME
Melian - Perl client to the Melian cache
VERSION
version 0.004
SYNOPSIS
use Melian;
#-----------------------------------------------
# OO INTERFACE (easy, name-based)
#-----------------------------------------------
my $melian = Melian->new(
'dsn' => 'unix:///tmp/melian.sock',
);
my $row = $melian->fetch_by_string_from( 'cats', 'name', 'Pixel' );
# Using IDs directly (faster)
my $row2 = $melian->fetch_by_string( 1, 1, 'Pixel' );
#-----------------------------------------------
# FUNCTIONAL INTERFACE (fastest)
#-----------------------------------------------
use Melian qw(fetch_by_string_with);
my $conn = Melian->create_connection(
'dsn' => 'unix:///tmp/melian.sock',
);
# Must use IDs in functional mode
my $row3 = fetch_by_string_with( $conn, 1, 1, 'Pixel' );
DESCRIPTION
Melian is a tiny, fast, no-nonsense Perl client for the Melian cache server.
Melian (the server) keeps full table snapshots in memory. Lookups are done entirely inside the server and returned as small JSON blobs. Think of it as a super-fast read-only lookup service.
This module gives you two ways to talk to Melian:
Object-Oriented Mode (easy)
Use table names and column names:
$melian->fetch_by_string_from( 'cats', 'name', 'Pixel' );
Behind the scenes, the module:
Looks up the table ID in the schema
Looks up the column ID in the schema
Builds the binary request to the server
Reads the reply and decodes JSON
This is the most convenient way. It is a little slower, because there is some name lookup and method dispatch each time.
Functional Mode (fastest)
Use this when you want raw speed:
my $conn = Melian->create_connection(...);
my $row = fetch_by_string_with( $conn, $table_id, $column_id, $key );
This avoids:
Method calls
Object construction
Lookup of table IDs and column IDs
It is simply: "write a request to the socket, read a response."
If you're chasing microseconds, this is the mode for you.
SCHEMA
Melian needs a schema so it knows which table IDs and column IDs correspond to which names. A schema looks something like:
people#0|60|id:int
Or:
people#0|60|id:int,cats#1|45|id:int;name:string
The format is simple:
table_name#table_id|refresh_period_in_seconds|column_name#column_id:column_type(multiple columns separated by;)
You do NOT need to write this schema unless you want to. If you do not supply one, Melian will request it automatically from the server at startup.
Accessing table and column IDs
Once the client is constructed:
my $schema = $melian->schema();
Each table entry contains:
{
name => "cats",
id => 1,
period => 45,
indexes => [
{ id => 0, column => "id", type => "int" },
{ id => 1, column => "name", type => "string" },
],
}
If you use the functional API, you probably want to extract these once at startup and store them in constants:
use constant {
'CAT_ID_TABLE' => 1,
'CAT_ID_COLUMN' => 0, # integer ID
'CAT_NAME_COLUMN' => 1, # string column
};
This saves name lookups on every request.
METHODS
new(...)
my $melian = Melian->new(
'dsn' => 'unix:///tmp/melian.sock',
'timeout' => 1, # Only relevant for TCP/IP
'schema_spec' => 'people#0|60|id:int',
);
Creates a new client and automatically loads the schema.
You may specify:
schema— already-parsed schema hashrefschema_spec— inline schema descriptionschema_file— path to JSON schema filenothing — Melian will ask the server for the schema
connect()
Opens the underlying socket. Called automatically by new().
disconnect()
Closes the socket.
fetch_raw($table_id, $column_id, $key_bytes)
Fetches a raw JSON string. Does NOT decode it. Assumes input is encoded correctly.
fetch_raw_from($table_name, $column_name, $key_bytes)
Same as above, but uses names instead of IDs.
fetch_by_string($table_id, $column_id, $string_key)
Fetches JSON from the server and decodes into a Perl hashref.
fetch_by_string_from($table_name, $column_name, $string_key)
Name-based version.
fetch_by_int($table_id, $column_id, $int)
Same as fetch_by_string, but the key is packed as a 32-bit integer.
fetch_by_int_from($table_name, $column_name, $int)
Name-based version.
FUNCTIONS
These functions form the high-speed functional interface. They require a socket returned by create_connection().
create_connection(%args)
Returns a raw socket connected to the server. Same options as new(), but no object is created.
fetch_raw_with($conn, $table_id, $column_id, $key_bytes)
fetch_by_string_with($conn, $table_id, $column_id, $string_key)
fetch_by_int_with($conn, $table_id, $column_id, $int)
These behave like the corresponding OO methods but skip object overhead and schema lookup.
table_of($schema, $table_name)
my $table_data = table_of( $schema, 'cats' );
my $table_id = $table_data->{'id'};
Fetches the table information from the schema.
column_id_of($table_data, $column_name)
my $table_data = table_of( $schema, 'cats' );
my $column_id = column_id_of( $table_data, 'name' );
Fetches the ID of a column from a given table metadata.
load_schema_from_describe($conn)
my $schema = load_schema_from_describe($conn);
This helps you retrieve the schema if you're using the functional interface. You can then use this schema to determine table and column IDs.
PERFORMANCE NOTES
OO mode is convenient but has overhead from name lookups and method calls.
ID-based OO mode is faster because it skips name lookups.
Functional mode is the fastest and is roughly equivalent to calling
syswriteandsysreaddirectly in Perl.If you care about performance, resolve table and column IDs once at startup.
AUTHORS
Sawyer X
Gonzalo Diethelm
COPYRIGHT AND LICENSE
This software is Copyright (c) 2025 by Sawyer X.
This is free software, licensed under:
The MIT (X11) License