hallidave/ruby-snmp — Issue #8: SNMP::Manager fails to initialize for a large number of threads
Author: t570796
Created: 2011-12-05 20:29:57+00:00
State: open

I have a program that uses ruby threads to open a large number of SNMP::Manager threads for simultaneous snmpget from different hosts. The program fails with the error below:

/usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/mib.rb:147:in `initialize': Too many open files - /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/data/ruby/snmp/mibs/TCP-MIB.yaml (Errno::EMFILE)
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/mib.rb:147:in `open'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/mib.rb:147:in `load_module'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:483:in `block in load_modules'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:483:in `each'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:483:in `load_modules'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:191:in `initialize'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:201:in `new'
from /usr/local/Cellar/ruby/1.9.2-p290/lib/ruby/gems/1.9.1/gems/snmp-1.0.4/lib/snmp/manager.rb:201:in `open'

I do realize that I am not using the latest version of ruby-snmp, but I believe the problem also exists in the latest version because SNMP::Manager constructor always creates new a SNMP::MIB instance, which includes a call to load_modules. This is very inefficient when a large number of SNMP::Manager instances need to be created simultaneously.

I suggest that you make it possible for different SNMP::Manager instances to share one SNMP::MIB instance across different threads. To maintain backward compatibility, you can add a new optional argument, say :mib, for SNMP::Manager constructor. The default value for :mib would be nil, for which the SNMP::Manager constructor will create a new SNMP::MIB instance. If :mib is not nil, then SNMP::Manager will try to use it and throw an exception if the :mib value is not an SNMP::MIB object.

Please let me know what you think of this suggestion.

Thank you for the excellent gem.