UNPKG

5.81 kBJavaScriptView Raw
1// actor.js
2// tests for l8 actors
3//
4// 2013/01/07 by JHR
5"use strict";
6
7var l8 = require( "l8/lib/actor.js")
8var Http = require( "http")
9var Connect = require( "connect")
10
11var de = l8.de
12var bug = l8.bug
13var mand = l8.mand
14
15/*
16 * Setup the stage, with an http server
17 */
18
19var app = Connect()
20app.use( Connect.static( 'public' ) )
21app.use( function( req, res ){ res.end( 'hello world\n' ) })
22var server = Http.createServer( app )
23l8.http_port = parseInt( process.env.PORT, 10) || 8080 // 80 requires sudo
24server.listen( l8.http_port )
25
26l8.stage( "local", server )
27
28/*
29 * Example. An half baked "logging" actor, using pattern matching
30 */
31
32var Logger = function(){ return l8.actor( "l8_logger", {
33 '"error", x': function( x ){ return l8.trace( "Error: " + x) },
34 'x': function( x ){ return l8.trace( "catch " + x) },
35 '"throw", e': function( e ){ l8.trace( "throw...", e); throw e }
36 //'...': function(){ l8.trace( "unsupported) }
37})}
38
39/*
40 * Example. A "logging" actor using method based dispatching
41 */
42
43var LoggerCount = 0
44
45var LoggerBis = function(){ return l8.actor( "l8_logger", {
46
47 "options" : function(){ return {} },
48
49 "Hello": function(){
50 l8.trace( "Hello")
51 },
52
53 trace: function(){
54 l8.trace.apply( l8, arguments)
55 },
56
57 error: function(){
58 var msg = Array.prototype.slice.call( arguments, 0)
59 msg[0] = "l8_logger actor, error: " + msg[0]
60 l8.trace.apply( l8, msg)
61 },
62
63 add: function(){ LoggerCount++ },
64
65 getSync: function(){
66 return LoggerCount
67 },
68
69 getAsync: function(){
70 var actor = this.ego
71 var reply = actor.reply
72 if( reply ){ reply( 0, LoggerCount) }
73 },
74
75 getPromise: function(){
76 var promise = l8.promise()
77 promise.resolve( LoggerCount)
78 return promise
79 },
80
81 getAsyncPromise: function(){
82 var promise = l8.promise()
83 promise.resolve( LoggerCount)
84 this.ego.reply( 0, promise)
85 },
86
87 catch: function(){
88 var msg = Array.prototype.slice.call( arguments, 0)
89 msg[0] = "Catch: " + msg[0]
90 return l8.trace.apply( l8, msg)
91 },
92
93 throw: function( e ){
94 l8.trace( "throw...", e); throw e
95 }
96})}
97
98/*
99 * Example, access to actor via a proxy. In this case, it's a mock because
100 * the proxied actor and the actual actor are on the same stage
101 */
102
103var LoggerTer = l8.proxy( "l8_logger")
104
105var url = "http://localhost"
106var port = l8.http_port || parseInt( process.env.PORT) || 80
107if( port ){ url += ":" + port }
108l8.trace( "url for local server: " + url)
109
110var Logger4 = l8.proxy( "l8_logger", url)
111
112function test_it( logger ){
113 l8.trace( "Start Logger. " + LoggerCount)
114 Logger()
115 var mylog = logger || l8.actor.lookup( "l8_logger")
116 de&&mand( mylog)
117 mylog.task && mylog.task.then(
118 function(){ l8.trace( "actor done")},
119 function(){ l8.trace( "actor dead")}
120 )
121 mylog.tell( "Hello" )
122 mylog.tell( "error", "is ok" )
123 mylog.tell( "does not understand", "this" )
124 mylog.tell( "add" )
125 l8.step( function( ){
126 return mylog.ask( "getSync" )
127 })
128 l8.step( function( r ){
129 l8.trace( "Count is " + LoggerCount + ". getSync->" + r)
130 de&&mand( !LoggerCount || r === LoggerCount )
131 })
132 l8.step( function( ){
133 return mylog.ask( "getPromise" )
134 })
135 l8.step( function( r ){
136 l8.trace( "getPromise->" + r)
137 de&&mand( !LoggerCount || r === LoggerCount )
138 })
139 l8.step( function( ){
140 return mylog.ask( "getAsync" )
141 })
142 l8.step( function( r ){
143 l8.trace( "getAsync->" + r)
144 de&&mand( !LoggerCount || r === LoggerCount )
145 })
146 l8.step( function( ){
147 return mylog.ask( "getAsyncPromise" )
148 })
149 l8.step( function( r ){
150 l8.trace( "getAsyncPromise->" + r)
151 de&&mand( !LoggerCount || r === LoggerCount )
152 })
153 l8.step( function( ){ mylog.tell([ "throw", "something that kills"]) })
154}
155
156l8.task( function(){
157 var t
158 var t0
159 var t1
160 var nloops = 1000
161 var nn
162 function delta( op ){
163 t1 = l8.now
164 var duration = (t1 - t0) / 1000
165 var ops_per_sec = nloops / duration
166 l8.trace( "" + LoggerCount + "/" + op + ". " + nloops + " in " + duration + " seconds")
167 l8.trace( "" + ops_per_sec + " operations per second")
168 }
169 l8.trace( "Scheduling test")
170 l8.step( function(){ test_it() })
171 l8.step( function(){ l8.sleep( 1000) })
172 l8.step( function(){ Logger = LoggerBis })
173 l8.step( function(){ test_it() })
174 l8.step( function(){ l8.sleep( 1000) })
175 l8.step( function(){ test_it( LoggerTer) })
176 l8.step( function(){ l8.sleep( 1000) })
177 l8.step( function(){ test_it( Logger4) })
178 l8.step( function(){ l8.sleep( 1000) })
179 l8.step( function(){
180 l8.trace( "Count is " + LoggerCount)
181 de&&mand( LoggerCount === 3 )
182 })
183 l8.step( function(){ l8.debug( false) })
184 l8.step( function(){
185 t = t0 = l8.now
186 nn = 0
187 })
188 l8.repeat( function(){
189 if( nn++ >= nloops ) l8.break;
190 return Logger4.ask( "getSync" )
191 })
192 l8.step( function(){ delta( "getSync") })
193 l8.step( function(){
194 t0 = l8.now
195 nn = 0
196 })
197 l8.repeat( function(){
198 if( nn++ >= nloops ) l8.break;
199 return Logger4.ask( "getAsync" )
200 })
201 l8.step( function(){ delta( "getAsync") })
202 l8.step( function(){
203 t0 = l8.now
204 nn = 0
205 })
206 l8.repeat( function(){
207 if( nn++ >= nloops ) l8.break;
208 return Logger4.ask( "getPromise" )
209 })
210 l8.step( function(){ delta( "getPromise") })
211 l8.step( function(){
212 t0 = l8.now
213 nn = 0
214 })
215 l8.repeat( function(){
216 if( nn++ >= nloops ) l8.break;
217 return Logger4.ask( "getAsyncPromise" )
218 })
219 l8.step( function(){ delta( "getAsyncPromise") })
220 l8.step( function(){
221 nloops = nloops * 4
222 t0 = t
223 delta( "remote get, overall")
224 })
225 l8.step( function(){ l8.debug( true) })
226 l8.step( function(){
227 l8.trace( "SUCCESS"); process.exit( 0)
228 })
229 l8.failure( function( e ){ l8.trace( "!!! unexpected error", e, e.stack) })
230})
231
232l8.countdown( 100)