160 lines
2.9 KiB
JavaScript
160 lines
2.9 KiB
JavaScript
"use strict";
|
|
|
|
const cl = global.botanLoader;
|
|
const Dragonfly = global.Dragonfly;
|
|
|
|
const EventEmitter = require( "events" ).EventEmitter;
|
|
|
|
const Client = cl.load( "botansx.modular.redisclient" );
|
|
const rand = cl.load( "botansx.utils.random" );
|
|
const SessConf = cl.load( "config.all" ).sx.modular.session;
|
|
|
|
class SessionEventArgs
|
|
{
|
|
constructor( message )
|
|
{
|
|
this.message = message;
|
|
}
|
|
}
|
|
|
|
class Session extends EventEmitter
|
|
{
|
|
static create( args )
|
|
{
|
|
if( !args ) args = [];
|
|
return new Session( args[0], args[1] );
|
|
}
|
|
|
|
constructor( hash, prefix, noIdReset )
|
|
{
|
|
super();
|
|
var _self = this;
|
|
|
|
if( hash && prefix )
|
|
hash = hash.replace( new RegExp( "^" + prefix + "\\." ), "" );
|
|
|
|
prefix = prefix ? prefix + "." : "";
|
|
|
|
this.id = prefix + hash;
|
|
this.ready = false;
|
|
this.exists = false;
|
|
|
|
Client.HGETALL( this.id, function( obj, err )
|
|
{
|
|
if( err ) throw err;
|
|
|
|
if( _self.exists = !!Object.keys(obj).length )
|
|
{
|
|
_self.__sess = {};
|
|
for( var i in obj )
|
|
_self.__sess[i] = obj[i];
|
|
}
|
|
// Auto reset the session id if no match
|
|
else if( !noIdReset )
|
|
{
|
|
_self.id = prefix + rand.uuid();
|
|
}
|
|
|
|
_self.ready = true;
|
|
_self.emit( "ready", _self );
|
|
} );
|
|
|
|
this.__sess = {};
|
|
this.__emitOk = ( m, err ) => {
|
|
_self.__emit( err, "set", new SessionEventArgs( m ) );
|
|
};
|
|
}
|
|
|
|
__emit( err, EventName, SessionArgs )
|
|
{
|
|
if( err ) throw err;
|
|
this.emit( EventName || "set", this, SessionArgs );
|
|
}
|
|
|
|
|
|
// Spawn session with specified id
|
|
spawn( expire, handler )
|
|
{
|
|
var ttl = ( expire === undefined ? SessConf.ttl : expire ) + 0;
|
|
this.__sess[ "lifespan" ] = ttl;
|
|
|
|
var _self = this;
|
|
Client.compatExec(
|
|
Client.multi()
|
|
.HSET( this.id, "spawn", new Date().getTime() )
|
|
.HSET( this.id, "lifespan", ttl )
|
|
.EXPIRE( this.id, ttl )
|
|
, handler || this.__emitOk
|
|
);
|
|
}
|
|
|
|
destroy( handler )
|
|
{
|
|
this.__sess = {};
|
|
Client.DEL( this.id, handler || this.__emitOk );
|
|
}
|
|
|
|
set( dict, handler )
|
|
{
|
|
var chain = Client.multi();
|
|
for( let k in dict )
|
|
{
|
|
var v = dict[k];
|
|
this.__sess[ k ] = v;
|
|
chain = chain.HSET( this.id, k, v );
|
|
}
|
|
|
|
Client.compatExec( chain, handler || this.__emitOk );
|
|
}
|
|
|
|
get( name )
|
|
{
|
|
return this.__sess[ name ];
|
|
}
|
|
|
|
// Get value asynchronously
|
|
aget( name, handler )
|
|
{
|
|
var _self = this;
|
|
Client.HGET(
|
|
this.id, name
|
|
, function( rep, err )
|
|
{
|
|
_self.__emitOk( err );
|
|
_self.__sess[ name ] = rep;
|
|
handler && handler( rep );
|
|
}
|
|
);
|
|
}
|
|
|
|
remove( name )
|
|
{
|
|
delete this.__sess[ name ];
|
|
Client.HDEL( this.id, name, this.__emitOk );
|
|
}
|
|
|
|
expire( seconds )
|
|
{
|
|
// expire > lifespan > SessConf.ttl
|
|
var ttl = ( seconds === undefined
|
|
? ( ( this.__sess[ "lifespan" ] === undefined )
|
|
? SessConf.ttl
|
|
: this.__sess[ "lifespan" ]
|
|
) : seconds ) + 0
|
|
;
|
|
|
|
this.__sess[ "lifespan" ] = ttl;
|
|
|
|
Client.compatExec(
|
|
Client.multi()
|
|
.HSET( this.id, "lifespan", ttl )
|
|
.EXPIRE( this.id, ttl )
|
|
, this.__emitOk
|
|
);
|
|
}
|
|
}
|
|
|
|
Session.SessionEventArgs = SessionEventArgs;
|
|
|
|
module.exports = Session;
|