Neko cacheModule and Tora Share

27.10.2013 3126 2

cacheModule :

When Apache gets a request it creates an instance of the neko VM. This VM is then cached (if cacheModule is activated) for future requests.
A sample code :

class App {
	
	static var i	= 0;
	
	static function main() {
		neko.Web.cacheModule( main );
		trace( i++ );
	}
}

Here, each time you refrsh the browser window, it increments the variable i : 0, 1, 2,...
Another example that shows that the cached module "lives" in the memory :

class App {
	
	static var i	= 0;
	static function main() {
		neko.Web.cacheModule( main );
		neo.vm.Thread.create( run );
		trace( i );
	}
	
	static function run() {
		while ( true ) {
			i++;
			Sys.sleep( 1 );
		}
	}
}

Here, the first time we refresh, it prints 1 but then each requests it grows up quickly, because each time a new thread that increments the variable i is created and so on...

Problem :

When several requests comes at the same time, several neko's VMs will be created each with its own new cache. So depending on how your Apache is configured, sometimes with a flow of simultaneous requests, when using mod_neko, it will result in a less responsive website because of caching time taken I presume. Using mod_tora, the problem can also occur but with much more simultaneous requests.

The cacheModule function permits to share a common initialization between the same modules running on the same VM.
But if you want to share data between several module's instances, comes into play mod_tora and its tora.Share class.

tora Share :

Since that with mod_tora, each request is given to the Tora server that runs a thread with an instance of a module, it suggests that we could share data between all the neko module's instances that are running on the same Tora server.
An example :

class App {
	
	static var share	= new tora.Share<Array<Int>>( "test", function() {
		return [ 0 ];
	});
	static function main() {
		var a	= share.get( false );
		trace( a );
		a[ 0 ]++;
	}
}

Here, we can see that at each refresh, the value contained in the shared array is incremented (as if it could be done using cacheModule with the previous seen restrictions...).
But when executing the code below :

class App2 {
	
	static var share	= new tora.Share<Array<Int>>( "test", function() {
		return [ 0 ];
	});
	static function main() {
		var a	= share.get( false );
		a[ 0 ]	+= 10;
	}
}

We can see, comming back to the previous window and refreshing, that the value contained in the shared array has grown by 10 : Using mod_tora with the Tora server, differents applications can share common data easily !
Note : The boolean as argument for the share's instance get function, defines the lock mode in the case of concurrent access. If set to true, another process that want to access the shared object will wait until it will be available (commited) if it's yet used.

Conclusion :

First, I recommend using cacheModule on mod_neko with caution. Depending on the website trafic it can slow down the stuff.
Then, the Tora's Share class offers an efficient way to share data between requests of the same module or not. It can be used as the simple cacheModule function (for sharing initialisations) but also as a database (for sessions in example...)

Commentaires

28.10.2013 à 13:35 RealyUniqueName

I beleive, the following code will let you avoid 'cacheModule' problem:

class App {
   //entry point while still not cached
   static public function main(){
      neko.Web.cacheModule(App.run);
      App.run();
   }
   static public function run(){
       //real app entry point without caching again
   }
}

Need to check this to be sure.

28.10.2013 à 14:09 Michal

The problem that occurs with cacheModule is that with simultaneous requests, it creates several VMs with their own module cache. And every time it creates a new VM, it does the initialization and it makes the module cached (which takes time and slow down when happen too often).
What about your code, it makes the static function main cached as others statics for example, so executed just once, and the static function run is executed each time. It can help if you want to initialize some things after the static initializations and the magic __init__ function too.

Laisser un commentaire

http://
×