Ever needed to adjust system limits in Ruby? If so, congratulations! You're in an infinitesimally-small minority. But at least now you can do it. Unless you're on Windows. Then you're still on your own.

Installation

It's a gem:

gem install rlimit

If you're the sturdy type that likes to run from git:

rake build; gem install pkg/rlimit-<whatever>.gem

Or, if you've eschewed the convenience of Rubygems, then you presumably know what to do already.

Usage

There are two main methods available to you. To read a resource limit, use RLimit.get, passing it one of the available RLimit::<TYPE> constants (more on that later), and optionally one of the symbols :hard or :soft:

>> RLimit.get(RLimit::NOFILE)
=> [1024, 65536]

>> RLimit.get(RLimit::NOFILE, :soft)
=> 1024

>> RLimit.get(RLimit::NOFILE, :hard)
=> 65536

>> RLimit.get(RLimit::CPU)
=> [:unlimited, :unlimited]

>> RLimit.get(RLimit::NOFILE, :lolidunno)
ArgumentError: Unknown limit type :lolidunno

>> RLimit.get("ohai!")
ArgumentError: Invalid rlimit resource specifier "ohai!"

A limit value is represented as either a non-negative integer, or the symbol :unlimited, to indicate that there is no limit on the resource. There are two possible return value "patterns", too -- if you don't specify a limit type, you get back a two-element array [<soft>, <hard>], whereas if you ask for one specific type of limit, you get back a scalar. If you're adventurous enough to try and pass an invalid argument, well, you get an ArgumentError for your troubles.

To set a resource limit, you've got RLimit.set:

# Set just a soft limit
>> RLimit.set(RLimit::NOFILE, 64)
=> true

# Set just a hard limit
>> RLimit.set(RLimit::NOFILE, nil, 128)
=> true

# Set both soft and hard limits
>> RLimit.set(RLimit::NOFILE, 64, 128)
=> true

# Set an unlimited soft limit
>> RLimit.set(RLimit::CORE, :unlimited)
=> true

# Try to increase a hard limit when not root
>> RLimit.set(RLimit::NOFILE, nil, 1048576)
RLimit::PermissionDenied: You do not have permission to raise hard limits

# Try to increase a soft limit above the hard limit
>> RLimit.set(RLimit::NOFILE, 128, 64)
RLimit::HardLimitExceeded: You cannot raise the soft limit above 64

Hopefully that should all be fairly self-explanatory. If not, well, there's more detailed documentation in the RDoc.

Available resource types

There is no guaranteed set of resource types which are available on all systems. To discover what is available on your system, call RLimit.resources, this will return an array containing the constants that are defined. You should reference setrlimit(2) for your system to determine exactly what they all mean.

If you wish to determine at runtime whether RLimit on your system supports a particular resource, you can use RLimit.supports?("RLIMIT_<res>") -- or just try to work with it anyway and rescue ArgumentError....

Soft and Hard Limits

The "soft" limit for an rlimit is the value that a process is currently restricted to; an attempt to exceed that limit will result in some sort of failure. However, a process can itself request to increase the value of a limit up to the "hard" limit. Only a process owned by root (or which has been granted the CAP_SYS_RESOURCE capability, on systems that support such a thing) can increase the hard limit.

Contributing

Bug reports should be sent to the Github issue tracker, or e-mailed. Patches can be sent as a Github pull request, or e-mailed.