
seen from United States

seen from United States

seen from Australia
seen from United Kingdom

seen from United Kingdom
seen from Mexico

seen from Netherlands
seen from Germany

seen from Romania
seen from Russia
seen from Yemen
seen from United States
seen from France

seen from Italy
seen from Italy

seen from United States

seen from Georgia

seen from Sweden
seen from China
seen from Brazil
重構 Em-Riak-Adv
雖然 EmRiak 實際使用上沒什麼問題, 但不易維護是當初趕出來所留下的致命傷..
這次重構花了兩天,結構的部分幾乎完全重寫.. 但大功能上不變.. 就不比較新舊版的差異. 直接寫出目前能幹嘛..
me=EmRiak.find("member1") me.link(:id=>"facebook_like10",:data=>facebook_like) .direction("outgoing").link_back(true).as(:facebook_likes) .do me.rel(:facebook_likes).depth(3).do me.start_as("member").depth(3).direction("outgoing") .as("facebook_like").dfs(){|results| do_something_after_you_get_results } me.start_as("member").depth(3).direction("outgoing") .as("facebook_like").bfs(){|results| do_something_after_you_get_results } searcher=Searcher.new searcher.find_commons(:between=>[2,3,4]).object_type(:member).item(:likes) searcher.find_commons(:between=>[2,3,4]).object_type(:member).item(:likes).depth(3)
以上.. :)
下一次的版本必須加入 trigger. 所以我們可以定義 trigger. 這樣會省去不少麻煩..
Asynchronous IO in Rack Middleware
At Xfire we've recently built a matchmaking service for users of our Battleground platform. The Matchmaker is a little Sinatra server that gets a request, creates a challenge, and tells the Xfire client about the challenge id.
For authentication, the client sends some parameters to the Matchmaker, and the Matchmaker calls an internal API call to make sure the user is who they say they are. I cooked up some simple middleware that performs auth, and by the time any request reached sinatra it either had the user_id or not depending out whether the user was authed.
The problem? During the HTTP request to the API, the server would sit around blocking doing nothing. (Okay, blah blah, threadpool, blah blah, but you get the point.)
Time for some fun with Asynchronous rack. Take the following synchronous Rack application:
https://gist.github.com/joeljackson/5519157
The application has two URLs it handles
1) "/sleep_time?sleep_time=#{some_time}"
2) Everything else
The first will sleep for a certain amount of seconds and return. For every other URL, the app does an http request to /sleep_time with an amount of time, waits for the response then says "hello world". If we tell thin (the webserver of choice for this example) to not use a threadpool for it's requests we can never even get a response because the request to "/sleep_time" will block waiting for the first request to finish it's IO. With two threads it can handle one request at a time, with 4 it can handle 2 requests at a time etc. Let's do better and rewrite this little rack app to do things asynchronously so it never blocks it's current thread.
https://gist.github.com/joeljackson/5519207
Now, when we do a request, it does a non blocking IO call to /sleep_time, then makes way for the next request, ALL ON THE SAME THREAD!! :-) This little guy will handle pretty much unlimited (okay, there's a limit, but it's not due to threads blocking) requests at the same time and smile the entire time.
What did we do? First each request that needed to be async did a "throw :async" instead of returning. (You can also return a status code of -1, or 0, but that's not consistent across webservers, so just use throw).
THEN, We did a non blocking IO call or non blocking sleep using EventMachine and called the async callback given to us by rack. Voila! Non blocking IO in your Rack app.
Now, I need to stop procrastinating and get back to work. If you're interested in seeing how we can build something a bit more complicated, check this out, but really this simple example should get you started.
Later!
(BTW. If you want to get the examples working to play with, then install thin and em-http-request and you'll be good to go!)
EDIT:
It occurs to me that this post might actually suggest a very bad habit to those looking to it to actually create middleware on a thin/eventmachine stack. The callback for the HTTP request will occur on the main reactor loop, which is fine if you are running thin unthreaded. Say however you are running threaded thin, and your app takes 500ms to do something very important like find all the latest in trendy cardigans for men. The reactor loop and all IO will be blocked for the entire 500ms, preventing other requests. It would behoove the prudent rubyist to actually call their app within a defer block so that it was executed within EventMachine's threadpool. An actual middleware implementation might look like this:
https://gist.github.com/joeljackson/5519815
設計 EmRiak 的背後
其實 Riak 也出來好久, 在社群的力強其實以一個新秀來說也還算強勁. 光以他 client 的數量就可得知. 其中 ruby clinet 就有將近 10 個? 但有三個好像都是官方貢獻的... :p 其實設計 EmRiak 的背後動機並不多, 除了覺得大部分的 client 對 em 的支援度並不好外, 大概就是使用起來的爽度了.. 使用別人的東西就是要習慣&接受他的寫法.. 如果自己有能力, 又很難接受別人寫法, 那麼自己寫是比較 Happy 的.. 只是多數狀況我們是沒時間, 沒心力, 或是有心無力.. 以 gem 來說, 繼上次自己寫 oAuth Server 之後. 這是第二個. 但想來自己之前也做了一個 micro framework 級別的東西.. 不過這就是話外了. 算起來, 這次的 gem 才是真的有 release 出來給公眾使用的.. 所以 Coding Style, 寫法, 嚴謹度都是會被審核, 所以自己寫起來也格外的戰戰兢兢.. 當然, 怎樣用心也還是不會寫得太好, 畢竟大神多, 自己是小咖.. 所以到最後就是秉持著 「可以動& 不要髒」的原則下去設計. 反正大神有用到&看不下就大概就會 commit 一堆 code 上來了.. :p EmRiak 目前的支援有 : * 基本的 crud * async 的 crud * Hybrid code style * MapReduce * SecondaryIndex 希望在 0.3 版會有 : * FullTextSearch * LinkWalk (其實已經寫一半了..@@) * MapReduceDeploymentTools * OrmModelWithSequel 加油.. 如果你對它有興趣, Commit 他吧 : EmRiak
Yield control back to `EventMachine`
Suppose we're listening to a message queue within an `EventMachine` scope. Suppose we've got a message, but it's not the one we're expecting, so we'd like to skip it hassle-free. How can we pass control back to EM without having to wrap everything in a long `if`? The short answer is: use `next`. Example follows. EventMachine.run do queue.subscribe do |message| if not message.match /known_to_us/ puts "Unknown message, skipping (message:#{message.inspect})" # Yield control back to EventMachine. next end # Proceed with reply. ... end end
Ruby's EventMachine – Part 2 : Asynchronous != Faster
Phil Whelan continues his series of posts digging into how to use EventMachine. http://rubyweekly.us1.list-manage.com/track/click?u=0618f6a79d6bb9675f313ceb2&id=a9339004c6&e=56d3c2b4c1 10mo. ANIVERSARIO DE LA CREACION DE LA UNIVERSIDAD DE LAS CIENCIAS INFORMATICAS... CONECTADOS AL FUTURO, CONECTADOS A LA REVOLUCION http://www.uci.cu http://www.facebook.com/universidad.uci http://www.flickr.com/photos/universidad_uci
Ruby on Rails @peepcode
https://peepcode.com/screencasts/ruby-on-rails
.
https://peepcode.com/products/play-by-play-tenderlove-ruby-on-rails
=>
Rails app that queries GitHub and returns an activity score for any user.
https://peepcode.com/products/play-by-play-jimweirich-ruby
=>
the task of building a library that enforces HTML form security
https://peepcode.com/products/eventmachine
https://peepcode.com/products/eventmachine-ii
=>
In Part I of the Meet EventMachine tutorial,we introduce the basic primitives of EventMachine: tasks, threads, queues, channels, and the useful Deferrable.
In Part II you’ll build several client/server applications including a WebSocket server and a basic Goliath API server.
https://peepcode.com/products/play-by-play-jbarnette
=>
a simple group chat application (근데 pusher 이용하는 것인 듯)
https://peepcode.com/products/meet-rails-3-i
https://peepcode.com/products/meet-rails-3-ii
https://peepcode.com/products/play-by-play-bernhardt
https://peepcode.com/products/scaling-ruby
Deepworld's MMO dream team: Ruby, MongoDB, and the cloud
MMO servers are hungry beasts. They run cpu-intensive game logic and coordinate the actions of hundreds of players, all of whom have persistent TCP and/or UDP connections. You don't have the same overhead as HTTP, but you've got a lot more overall communication, and any real latency quickly becomes unforgiveable.
There's a lot of debate over the performance of Ruby versus other technologies, but if you can scale horizontally, it doesn't matter so much. If your developers know Ruby and can bust it out five times faster than a Java or C++ server, you're going to save time and money.
So for Deepworld, we chose Ruby, knowing in the back of our minds that we could also extend it with C if we needed to. Which we did - but only for our convoluted game logic and physics. After all, EventMachine is a wondrous and fast reactor-based server, the Ruby equivalent of Node.js except with a decade of maturity under its belt. We actually did try Node.js out at first, because it's apparently The Hotness, plus coffeescript is pretty sweet. However, the integration challenges and relative youth of its many libraries quickly scared us off. The argument for Node.js as compared to EventMachine is generally "Node.js is built from the ground up to be callback-based, whereas you have to use specific libraries in EventMachine, and also V8 blah blah."
<snark> Wait! I have to use SPECIFIC libraries! That is so much work! Clearly I should instead go with a fledgling technology, because bandwagons are fun. </snark>
Speaking of bandwagons, we opted to use MongoDB as our data store, and it has been rather awesome. Schemas are for suckers.
We've eked out a ton of performance with relatively few problems by using a fairly simple architectural strategy:
Spin up lots of servers, each hosting multiple worlds (effectively sharding the MMO's universe)
When a world loads, download (and "own") the data
Keep things mostly in memory, synching to MongoDB every so often
Be sure to synch to MongoDB if everything goes boom
Spin down when a world unloads
Ruby has been more than capable of handling loads in this fashion, and as mentioned, we can still get the benefit of super-fast C code with custom extensions. Our liquid dynamics, for example, are written in C because they involve a crapload of world lookups and changes. We also use C to generate noise for procedural world generation, but most of our logic is just good ol' vanilla Ruby.
Ultimately, developers are expensive (and grumpy), and servers are cheap.
We haven't done huge scaling tests yet, but we have successfully run a hundred simulated players on a world (over TCP) without too much trouble. And since we can limit the amount of players per world, and worlds per server, we're fairly confident things will be okay-ish. Naturally, we may be proven wrong, but it's worth it.
Because we're Rubyists, through and through.