-
Notifications
You must be signed in to change notification settings - Fork 30
Creating your session engine
It is possible to create custom engines for kemal-session. To do so, you have to create a class that inherits from the abstract class `Session::Engine. This abstract class defines methods that your engine has to provide:
def initialize(options : Hash(Symbol, String))
Your engine can take a set of optional options upon initializing. For the FileSystemEngine
this would be the folder to store the sessions in and for a database engine it could be for host, database, user and password.
def run_gc
This method will be called by Session periodically to clean up old, unremoved sessions. The FileSystemEngine
simply deletes the corresponding files, a database engine might need to remove entries from a table etc.
When a developer is using kemal-session, they're required to define the type to be saved in session storage. Currently, the types supported are Int32, Float64, String, and Bool. The raw type names (e.g. Int32) are not used to define the names of the methods. Instead, short form type names are used:
Type | Method Short Name |
---|---|
Int32 | int |
Float64 | float |
String | string |
Bool | bool |
For each of the base types, four different methods need to be created. If any of the methods are missing from the implementation, you will get an error during compilation because Session::Engine
is defined as an abstract class. Session::Engine
requires these methods but its up to the engine itself how it will save the session data in the data store.
def int(session_id : String, k: String, v : Int32)
# set the value of k to v for session session_id in your file, database etc.
end
def int(session_id : String, k: String) : Int32
# return the value of k for session session_id
end
def int?(session_id : String, k : String) : Int32?
# return the value of k for session session_id if it is set, otherwise nil
end
def ints(session_id : String) : Hash(String, Int32)
# return a hash of k => v pairs for session session_id
end
One of the more unique types that have to be saved in the engine is StorableObject. StorableObject
is an abstract type that used by the developer to define subclasses in which the instances are saved in session storage. The defined subclasses need to respond to two different methods, #unserialize
and .serialize
. When a StorableObject is serialized via the .serialize
method, it returns a String and that then can be saved by the storage engine. The unserialize class method will recreate an instance of the object defined by the developer. The Redis kemal-session engine has an example of how .serialize
and #unserialize
works.
Just like the base types, StorableObject has a set of short-form method names. The engine must respond to a set of object
methods to handle StorableObject:
def object(session_id : String, k: String, v : StorableObject)
# set the value of k to v for session session_id in your file, database etc.
end
def object(session_id : String, k: String) : StorableObject
# return the value of k for session session_id
end
def object?(session_id : String, k : String) : StorableObject?
# return the value of k for session session_id if it is set, otherwise nil
end
def objects(session_id : String) : Hash(String, StorableObject)
# return a hash of k => v pairs for session session_id
end
If you have created an engine name MyEngine
you can tell kemal-session
to use this new engine:
Session.config.engine = MyEngine.new({option_for_your_engine: "value"})