Ruby API support
Status
The uWSGI API for Ruby is still incomplete (QueueFramework, SharedArea, custom routing and SNMP being the most missing players). The DSL will be extended as soon as the various API calls are ready.
Currently available API functions and constants (available in the UWSGI ruby module) are
- UWSGI.suspend
- UWSGI.masterpid
- UWSGI.async_sleep
- UWSGI.wait_fd_read
- UWSGI.wait_fd_write
- UWSGI.async_connect
- UWSGI.signal
- UWSGI.register_signal
- UWSGI.register_rpc
- UWSGI.signal_registered
- UWSGI.signal_wait
- UWSGI.signal_received
- UWSGI.add_cron
- UWSGI.add_timer
- UWSGI.add_rb_timer
- UWSGI.add_file_monitor
- UWSGI.cache_get
- UWSGI.cache_get!
- UWSGI.cache_exists
- UWSGI.cache_exists?
- UWSGI.cache_del
- UWSGI.cache_set
- UWSGI.cache_set
- UWSGI.cache_set!
- UWSGI.cache_update
- UWSGI.cache_update!
- UWSGI.setprocname
- UWSGI.set_warning_message
- UWSGI.lock
- UWSGI.unlock
- UWSGI.mem
- UWSGI.mule_get_msg
- UWSGI.request_id
- UWSGI.mule_id
- UWSGI.mule_msg
- UWSGI.worker_id
- UWSGI.log
- UWSGI.logsize
- UWSGI.i_am_the_spooler
- UWSGI.send_to_spooler
- UWSGI.spool
- UWSGI::OPT
- UWSGI::VERSION
- UWSGI::HOSTNAME
- UWSGI::NUMPROC
- UWSGI::PIDFILE
- UWSGI::SPOOL_OK
- UWSGI::SPOOL_RETRY
- UWSGI::SPOLL_IGNORE
uWSGI DSL
In parallel to the uWSGI API Python decorators, a DSL for Ruby is available, allowing elegant access to the uWSGI API.
The module is available as uwsgidsl.rb
in the source distribution. You can put this code in your config.ru
file, or use the rbrequire
option to auto-include it.
timer(n, block)
Execute code at regular intervals.
- timer 30 do |signum|
- puts "30 seconds elapsed"
- end
rbtimer(n, block)
As timer, but using a red-black tree timer.
- rbtimer 30 do |signum|
- puts "30 seconds elapsed"
- end
filemon(path, block)
Execute code at file modifications.
- filemon '/tmp' do |signum|
- puts "/tmp has been modified"
- end
cron(hours, mins, dom, mon, dow, block)
Execute a task periodically using the CronInterface.
- cron 20,16,-1,-1,-1 do |signum|
- puts "It's time for tea."
- end
signal(signum, block)
Register code as a signal handler for the SignalFramework.
- signal 17 do |signum|
- puts "Signal #{signum} was invoked."
- end
postfork(block)
Execute code after each fork()
.
- postfork do
- puts "uWSGI server called fork()"
- end
rpc(name, block)
Register code as a uWSGI RPC Stack function.
- rpc 'helloworld' do
- return "Hello World"
- end
- rpc 'advancedhelloworld' do |x,y|
- return "x = #{x}, y = #{y}"
- end
mule(id?, block)
Execute code as a Mule brain.
- mule 1 do # Run in mule 1
- puts "I am the mule #{UWSGI.mule_id}"
- end
- mule do # Run in first available mule
- puts "I am the mule #{UWSGI.mule_id}"
- end
After the function returns, the mule will be brainless. To avoid this, put the code in a loop, or use muleloop
.
muleloop(id?, block)
Execute code in a mule in looped context.
- muleloop 3 do
- puts "I am the mule #{UWSGI.mule_id}"
- sleep(2)
- end
SpoolProc
A subclass of Proc
, allowing you to define a task to be executed in the Spooler.
- # define the function
- my_long_running_task = SpoolProc.new {|args|
- puts "I am a task"
- UWSGI::SPOOL_OK
- }
- # spool it
- my_long_running_task.call({'foo' => 'bar', 'one' => 'two'})
MuleFunc
Call a function from any process (such as a worker), but execute in a mule
- i_am_a_long_running_function = MuleFunc.new do |pippo, pluto|
- puts "i am mule #{UWSGI.mule_id} #{pippo}, #{pluto}"
- end
- i_am_a_long_running_function.call("serena", "alessandro")
The worker calls i_am_a_long_running_function()
but the function will be execute asynchronously in the first available mule.
If you want to run the function on a specific mule, add an ID parameter. The following would only use mule #5.
- i_am_a_long_running_function = MuleFunc.new 5 do |pippo,pluto|
- puts "i am mule #{UWSGI.mule_id} #{pippo}, #{pluto}"
- end
- i_am_a_long_running_function.call("serena", "alessandro")
Real world usage
A simple Sinatra app printing messages every 30 seconds:
- # This is config.ru
- require 'rubygems'
- require 'sinatra'
- require 'uwsgidsl'
- timer 30 do |signum|
- puts "30 seconds elapsed"
- end
- get '/hi' do
- "Hello World!"
- end
- run Sinatra::Application
Or you can put your code in a dedicated file (mytasks.rb
here)
- require 'uwsgidsl'
- timer 30 do |signum|
- puts "30 seconds elapsed"
- end
- timer 60 do |signum|
- puts "60 seconds elapsed"
- end
and then load it with
- uwsgi --socket :3031 --rack config.ru --rbrequire mytasks.rb --master --processes 4