The Dispatcher is the beating heart of Ares. Using an EventMachine reactor library, it ensures that commands and events are queued up and handled in an orderly fashion.
The Dispatcher handles three main types of dispatches:
Whenever it gets one of these dispatches, it goes through all the plugins to see if anybody wants to handle it. Commands and Web Requests may only be handled by a single plugin. Events may be handled by any plugin.
A plugin specifies what dispatches it handles through pre-defined methods that the Dispatcher knows to call:
get_web_request_handler. Each of these methods may either return a handler class (like
TinkerCmd) or nil if the plugin doesn’t care about the dispatch.
Never ever call EventMachine methods directly - always go through the Dispatcher. If you don't have appropriate error checking and something goes wrong, you can crash the entire game.
Although the main reactor is single-threaded (ensuring all commands are handled in order), it is possible to spawn a background task to handle long-running tasks without blocking the main command queue. This is particularly important for calls to external websites that may take some time.
Global.dispatcher.spawn("Performing backup.", client) do ... perform backup code ... end
Exercise caution when using spawns. Most Ares code is threadsafe because it's stand-alone helper methods and command classes created on demand, but you can cause weird effects if your spawned task starts changing database fields on a character while other commands are still running.
A timer delays code until some time has elapsed. The code will be processed in queue order - it’s not spawned into a background task - it will just be delayed. For example, the following code waits 2 seconds and then does an emit:
Global.dispatcher.queue_timer(2, "Tell guest their name", client) do client.emit_success t('login.guest_name', :name => guest.name) end
Ares timers do not have stopwatch precision. The code will wait for *at least* the specified time, but it may take a little longer depending on how busy the system is.
The Dispatcher provides there ways for code to add things to the queue: