Understanding Daemonkit

Hey all,
Many of us knows what daemons are in linux. These are processes or programs that run in background with little or no user intervention.
Now we can write daemons in ruby too. And for doing so we can use Daemon-Kit(https://github.com/kennethkalmer/daemon-kit).
Now the daemon can do the task continuously or do it at particular interval of time or do it depending on a particular event.
Daemon-Kit provides a skeleton to write these different types of daemons with the help of differnt types of generators.(XMPP bot,AMQP client,Nanite agent,Cron-style,ruote remote participants). Of these XMPP and AMQP are event based and amqp is specifically based on queuing system, and Nanite agent gives a nanite structured daemon while Cron-style is used to write daemons that perform certain task at particular interval amount of time.
First install the gem daemon-kit
gem install daemon-kit
For viewing the help of daemonkit you can give the command,
daemon-kit -h
Now to build a simple daemon which would use a default generator you can use,
daemon-kit mydaemon
For building a daemon with a generator you can use,
daemon-kit mydaemon -i amqp</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">daemon-kit mydaemon -i cron
Now for starting the daemon first you go into the daemon directory and then give the command,
cd mydaemon</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">./bin/mydaemon
which would start the daemon in foreground which is used for testing if everhting is working.The daemon would die as you close the terminal.
To purely daemonize it you can use
./bin/mydaemon start
This would start the daemon in daemonized form and would continue to run in background till any untoward exception occurs.
To stop the daemon running in background you can use the commnad
./bin/mydaemon stop
Now the basic tree structure of a daemon would be something similar to this.
</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">my_cron_daemon</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── bin</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── my_cron_daemon</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── config</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── arguments.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── boot.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── environment.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── environments</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   │   ├── development.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   │   ├── production.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   │   └── test.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── post-daemonize</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   │   └── readme</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── pre-daemonize</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│       ├── cron.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│       ├── readme</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│       └── safely.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── Gemfile</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── lib</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── my_cron_daemon.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── libexec</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── my_cron_daemon-daemon.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── log</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── Rakefile</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── README</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── script</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── console</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── destroy</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── generate</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── spec</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── my_cron_daemon_spec.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   ├── spec_helper.rb</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── spec.opts</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── tasks</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">│   └── rspec.rake</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">├── tmp</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">└── vendor</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">
The pre-daemonize folder consists of all the files that are required before the daemon starts. The cron.rb can be used to require all the gems that are needed for the daemon.
The my_cron_daemon.rb in lib folder is automatically loaded when the daemon starts. Additonal ruby files can be created in the lib folder and can be required from the cron.rb in pre-daemonize for utilization.This can be done as,
excluded_files = [File.join(DaemonKit.root, 'lib', "my_cron_daemon.rb")]</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">(Dir.glob(File.join(DaemonKit.root, "lib", "*.rb")) - excluded_files.flatten).each{|f| require f}
This is done because my_cron_daemon.rb in lib is automatically loaded and requiring it multiple times might cause issues.
The post-daemonize folder is used to place those files that needs to be loaded after the daemon starts.
Similarly a yml file(e.g config.yml) which holds all the configuration setting can be created in the config and loaded into the daemon using,
CONFIG = DaemonKit::Config.load("config.yml")
Here CONFIG can be used anywhere in the daemon later on to access the required configuration.
Now you can also add ruby files that connect to a particular database and query data by putting those in lib. These files would have a structure similar to the ruby files in models of rails application.
As for the database connection you can put these pieces of code in cron.rb in pre-daemonize which establishes the databse connection,
ActiveRecord::Base.configurations = CONFIG[:database_configuration]</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ActiveRecord::Base.establish_connection(CONFIG[:database_configuration])
where “database_configuration” is placed in the config.yml
Now we can also have the daemon as a request-response serving program similar to a rack-server, This can be done by using eventmachine.
Daemons are a difficult to debug. Because they can just cause  your program to fail when a request comes in. Normally we write a code in a normal Ruby program and run it to test all the functionallity and then put it within the daemon. This helps in ensuring that your logic is proper. For further debugging I use a lot of puts statements when coding later switching to DaemonKit.logger.info or .debug to dump the statements to the log.
DaemonKit.logger.info "I am the DaemonKit logger info"
Here is a link to a basic daemon which is based on default,cron generator.
https://github.com/kelvink/My-Basic-Daemon
https://github.com/kelvink/My-Cron-Daemon
Also here is a link for the daemon to work as a rack server using evenmachine.
https://github.com/kelvink/My-EM-Daemon
Thus we can have a ruby daemon which perform specific task as required and when required.

Hey all,

Many of us knows what daemons are in linux. These are processes or programs that run in background with little or no user intervention.

Now we can write daemons in ruby too. And for doing so we can use Daemon-Kit.

Now the daemon can do the task continuously or do it at particular interval of time or do it depending on a particular event.

Daemon-Kit provides a skeleton to write these different types of daemons with the help of differnt types of generators.(XMPP bot,AMQP client,Nanite agent,Cron-style,ruote remote participants). Of these XMPP and AMQP are event based and amqp is specifically based on queuing system, and Nanite agent gives a nanite structured daemon while Cron-style is used to write daemons that perform certain task at particular interval amount of time.

First install the gem daemon-kit

gem install daemon-kit

For viewing the help of daemonkit you can give the command,

daemon-kit -h

Now to build a simple daemon which would use a default generator you can use,

daemon-kit mydaemon

For building a daemon with a generator you can use,

daemon-kit mydaemon -i amqp

daemon-kit mydaemon -i cron

Now for starting the daemon first you go into the daemon directory and then give the command,

cd mydaemon

./bin/mydaemon

which would start the daemon in foreground which is used for testing if everything is working.The daemon would die as you close the terminal.

To purely daemonize it you can use

./bin/mydaemon start

This would start the daemon in daemonized form and would continue to run in background till any untoward exception occurs.

To stop the daemon running in background you can use the command

./bin/mydaemon stop

Now the basic tree structure of a daemon would be something similar to this.


my_cron_daemon

├── bin

│   └── my_cron_daemon

├── config

│   ├── arguments.rb

│   ├── boot.rb

│   ├── environment.rb

│   ├── environments

│   │   ├── development.rb

│   │   ├── production.rb

│   │   └── test.rb

│   ├── post-daemonize

│   │   └── readme

│   └── pre-daemonize

│       ├── cron.rb

│       ├── readme

│       └── safely.rb

├── Gemfile

├── lib

│   └── my_cron_daemon.rb

├── libexec

│   └── my_cron_daemon-daemon.rb

├── log

├── Rakefile

├── README

├── script

│   ├── console

│   ├── destroy

│   └── generate

├── spec

│   ├── my_cron_daemon_spec.rb

│   ├── spec_helper.rb

│   └── spec.opts

├── tasks

│   └── rspec.rake

├── tmp

└── vendor

The pre-daemonize folder consists of all the files that are required before the daemon starts. The cron.rb can be used to require all the gems that are needed for the daemon.

The my_cron_daemon.rb in lib folder is automatically loaded when the daemon starts. Additonal ruby files can be created in the lib folder and can be required from the cron.rb in pre-daemonize for utilization.This can be done as,

excluded_files = [File.join(DaemonKit.root, 'lib', "my_cron_daemon.rb")]

(Dir.glob(File.join(DaemonKit.root, "lib", "*.rb")) - excluded_files.flatten).each{|f| require f}

This is done because my_cron_daemon.rb in lib is automatically loaded and requiring it multiple times might cause issues.

The post-daemonize folder is used to place those files that needs to be loaded after the daemon starts.

Similarly a yml file(e.g config.yml) which holds all the configuration setting can be created in the config and loaded into the daemon using,

CONFIG = DaemonKit::Config.load("config.yml")

Here CONFIG can be used anywhere in the daemon later on to access the required configuration.

Now you can also add ruby files that connect to a particular database and query data by putting those in lib. These files would have a structure similar to the ruby files in models of rails application.

As for the database connection you can put these pieces of code in cron.rb in pre-daemonize which establishes the databse connection,

ActiveRecord::Base.configurations = CONFIG[:database_configuration]

ActiveRecord::Base.establish_connection(CONFIG[:database_configuration])

where “database_configuration” is placed in the config.yml

Now we can also have the daemon as a request-response serving program similar to a rack-server, This can be done by using eventmachine.

Daemons are a difficult to debug. Because they can just cause  your program to fail when a request comes in. Normally we write a code in a normal Ruby program and run it to test all the functionallity and then put it within the daemon. This helps in ensuring that your logic is proper. For further debugging I use a lot of puts statements when coding later switching to DaemonKit.logger.info or .debug to dump the statements to the log.

DaemonKit.logger.info "I am the DaemonKit logger info"

Here are links to  basic daemon which is based on default,cron generator and rack server using eventmachine.

https://github.com/kelvink/My-Basic-Daemon,

https://github.com/kelvink/My-Cron-Daemon,

https://github.com/kelvink/My-EM-Daemo

Thus we can have a ruby daemon which perform specific task as required and when required.

2 comments On Understanding Daemonkit

Leave a Reply to Kelvin Kunjukutty Cancel Reply

Your email address will not be published.

Site Footer