Showing posts with label otaku. Show all posts
Showing posts with label otaku. Show all posts

Sunday, July 18, 2010

Tidying up specs suite with otaku

In the specs suite of cross-stub, i've built a custom echo server using this approach to support testing of stubbing in another process. Nothing wrong with it, except that it is not so fun & clean. Anyway, over the weekend, i've extracted out the echo server code, and put it inside a new & fun project otaku.

Here's my tidied up specs (which serve as a good example usage of otaku):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
shared 'has other process setup' do

behaves_like 'has standard setup'

before do
# Don't start the service if it has already been started.
$service_started ||= (
Otaku.start do |data|

# Pull in all the helpers, __FILE__ magically converts to path of this file,
# even after otaku's internal marshalling/unmarshalling.
require File.join(File.dirname(__FILE__), '..', 'includes')

# Some processing ... using helpers & class definitions pulled in by the above
# require statement.
store_type, method_call_args = data.match(/^(.*?)\/(.*)$/)[1..2]
CrossStub.refresh(cache_store($prev_store_type)) if $prev_store_type
CrossStub.refresh(cache_store($prev_store_type = store_type))

# Actually capturing of error is not necessary, cos Otaku captures any error &
# wrap it up in Otaku::DataProcessError.
do_local_method_call(method_call_args) rescue $!.message
end

true
)
end

end

at_exit do
# Stops otaku if it has been started, only this process is abt to exit.
$service_started && Otaku.stop
end

Building a simple server/client with eventmachine 2

Following previous entry, i've come up with a drop dead simple service framework based on eventmachine, just a fun project actually, as u can see from its name "OTAKU". Since code speaks a thousand words, especially for someone like me, let's jump straight into some coding:
1
2
3
4
5
6
require 'otaku'

# Starting to otaku service
Otaku.start do |data|
result = '~ %s ~' % data
end

1
2
3
4
require 'otaku'

# client sending a process request to otaku service
Otaku.process('hello') # >> '~ hello ~'

Of course, life is never as simple as the above, since we have Otaku.start accepts a proc, most people tend to code in-a-taken-for-granted-way taking advantage of contextual references:
1
2
3
4
5
6
mark = '*'
Otaku.start do |data|
'%s %s %s' % [mark, data, mark]
end

Otaku.process('hello') # #<NameError: undefined local variable or method `mark' for ...

Now now, really unexpected rite ? The reason is that otaku converts the proc passed to Otaku.start, convert it to plain ruby code, & eval in the server process, thus, naturally, any contextual references are lost. As a workaround:
1
2
3
4
5
Otaku.start(:mark => '*') do |data|
'%s %s %s' % [mark, data, mark]
end

Otaku.process('hello') # >> '* hello *'

Well, i must admit this workaround is abit not-so-comfortable ... anyway, i'm still thinking (hard) on how the contextual references can be extracted under the hood, without having user to go through the trouble of declaring the context hash explicitely. Anyway, this is what otaku has to offer for now :]

Have a look at this slightly more complicated usage of otaku.

Labels