2

I'm running a script (running on an AWS EC2 instance) that continually pulls state legislative data from an API, and persists it to a SQLite3 .db file. When I try to run the script as a daemon in the background, the process immediately stops and I'm given the following error.

stateleg.rb: process with pid 4666 started.
Traceback (most recent call last):
    11: from stateleg_daemon.rb:4:in `<main>'
    10: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons.rb:149:in `run'
     9: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/cmdline.rb:121:in `catch_exceptions'
     8: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons.rb:150:in `block in run'
     7: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/controller.rb:59:in `run'
     6: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:307:in `start'
     5: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:228:in `start_load'
     4: from /usr/local/rvm/gems/ruby-2.5.1/gems/daemons-1.3.1/lib/daemons/application.rb:228:in `load'
     3: from /home/ubuntu/stateleg.rb:8:in `<top (required)>'
     2: from /home/ubuntu/stateleg.rb:8:in `new'
     1: from /usr/local/rvm/gems/ruby-2.5.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:89:in `initialize'
/usr/local/rvm/gems/ruby-2.5.1/gems/sqlite3-1.4.1/lib/sqlite3/database.rb:89:in `open_v2': unable to open database file (SQLite3::CantOpenException)

When I try to run the script in the foreground, the script runs perfectly, and the necessary information is written to the .db file.

How can I make this daemon open the database file? Are SQLite3 and Ruby daemons in some way incompatible? Any information at all would be tremendously helpful.

This is the entirety of the daemon script.

require 'daemons'

Daemons.run('stateleg.rb')
FakeBenJay
  • 41
  • 2

1 Answers1

1

When something is "daemonized" it's usually running in a different working directory than the one you expect. This is especially true for services that are spun up on boot, such as through systemd, or on cron.

In order to account for this you need to specify the full path to files you're intending to work with. These are called absolute paths since they're not impacted by the current working directory. /a/b/c is an absolute path, it starts with /, but b/c is relative. If you're in /a it's equivalent, but it won't work outside of that scope.

If you know the location of that file relative to your script, you can usually do this:

Daemons.run(File.expand_path('stateleg.rb', __dir__))

Where __dir__ is the directory in which the currently executing script file is stored.

tadman
  • 208,517
  • 23
  • 234
  • 262