Forum: Ruby idioms for separating out OS-specific stuff

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Joe Van D. (Guest)
on 2006-03-08 23:18
(Received via mailing list)
I have a few functions that:
  - get the current user's login name
  - checks to see what the CPU % of a process is (non the Ruby
process, another process).  This includes all the threads that the
process has
  - forks a new process
  - sees if a process is still running
  - gets the utilization percentage of a NIC on the machine
  - the load average of the machine
  - the number of CPUs on a given machine

This is all working fine on Linux with kernel 2.4.  However, the code
doesn't quite run correctly on a 2.6 kernel (not sure why yet).  And
forget about OS X and Windows and *BSD.

Are there any good Ruby idioms for managing the separate OS-specific
functions?

My first thought:
module SystemSpecificMethods
 module Linux
    # generic linux functions in here

    module 2.4
      # linux 2.4 functions in here
    end

    module 2.6
      # linux 2.6 functions in here
    end
  end

  module Windows
    # Windows functions here
  end

  module BSD
    # OS X and maybe *BSD functions here
  end
end

And then probe (somwhow?) to figure out what OS I'm running on and
then including the correct modules into my code.  So, if I were using
Linux 2.6, I'd include SystemSpecificFunctions::Linux and
SystemSpecificFunctions::Linux::2.6.

But I'm sure that's a pretty dumb way of doing it, as I'm not terribly
bright.

Joe
Logan C. (Guest)
on 2006-03-08 23:46
(Received via mailing list)
On Mar 8, 2006, at 4:18 PM, Joe Van D. wrote:

> And then probe (somwhow?) to figure out what OS I'm running on and
> then including the correct modules into my code.

As far as probing goes...

irb(main):026:0> Config::CONFIG['host_os']
=> "darwin8.4.0"
irb(main):027:0> Config::CONFIG['arch']
=> "powerpc-darwin8.4.0"

etc.

You can also try shelling out and calling uname, but that of course
won't work on windows for example.

logan:/Users/logan% uname -s
Darwin
logan:/Users/logan% uname -r
8.5.0
logan:/Users/logan% uname -v
Darwin Kernel Version 8.5.0: Sun Jan 22 10:38:46 PST 2006;
root:xnu-792.6.61.obj~1/RELEASE_PPC
logan:/Users/logan% uname -a
Darwin logan-capaldos.poly.edu 8.5.0 Darwin Kernel Version 8.5.0: Sun
Jan 22 10:38:46 PST 2006; root:xnu-792.6.61.obj~1/RELEASE_PPC Power
Macintosh powerpc
unknown (Guest)
on 2006-03-08 23:52
(Received via mailing list)
On Mar 8, 2006, at 4:18 PM, Joe Van D. wrote:
> Are there any good Ruby idioms for managing the separate OS-
> specific functions?

Lots of ways to do this.  Here is another thought:

class A
   case RUBY_PLATFORM
   when /linux/
        def alpha; 'linux implmentation'; end
   when /darwin/
        def alpha; 'darwin implementation'; end
   else
        def alpha; 'default implementation'; end
   end
   def beta; 'works on all systems'; end
end

puts A.new.alpha	# 'darwin implementation' (on Mac OS X)
puts A.new.beta         # 'works on all systems'

Gary W.
Joel VanderWerf (Guest)
on 2006-03-09 00:01
(Received via mailing list)
Joe Van D. wrote:
...
>   - gets the utilization percentage of a NIC on the machine
...

I've been wondering how to do that, either on 2.4 or 2.6. What are you
using?
Joe Van D. (Guest)
on 2006-03-09 00:08
(Received via mailing list)
On 3/8/06, Joel VanderWerf <removed_email_address@domain.invalid> wrote:
> Joe Van D. wrote:
> ...
> >   - gets the utilization percentage of a NIC on the machine
> ...
>
> I've been wondering how to do that, either on 2.4 or 2.6. What are you
> using?

I don't have the code in front of me, but there's a file in /proc
(maybe /proc/net?) that details the TX and RX information for each NIC
(in packets or bytes transferred).  Keep track of the total amount of
stuff transferred over time, divide by the capacity of the NIC over
that time period (I think I cheat and assume gigabit NICs, since
that's all we have here), and there you are.

It turns out that it's pretty hard to get the utilization much above
10%.  But I'm not sure of the best way of generating a ton of useless
network traffic.

Joe
unknown (Guest)
on 2006-03-09 00:56
(Received via mailing list)
Quoting Joe Van D. <removed_email_address@domain.invalid>:

>   - the number of CPUs on a given machine
...

> And then probe (somwhow?) to figure out what OS I'm running on
> and
> then including the correct modules into my code.  So, if I were
> using
> Linux 2.6, I'd include SystemSpecificFunctions::Linux and
> SystemSpecificFunctions::Linux::2.6.

Maybe it would be better to break up the modules by feature rather
than platform.  Forking processes is the same on BSD and all Linux
flavors, for example.

So, you'd have a module for POSIX-style fork, for example, and
another for /proc/cpuinfo.  The former would provide just the
process creation methods, and the latter would provide just the
methods for enumerating CPUs.

Then you could give each module a singleton method to test for the
presence of its associated feature -- e.g. check whether
'/proc/cpuinfo' exists.

Then you could iterate through those modules and simply include the
ones whose feature checks pass.  Probably you'd want to write some
additional stuff to wrap that process too.

Anyway, advantages:

 - automatically deal with unknown systems that have combinations of
known features

 - avoid duplication between different platforms with common
features

-mental
This topic is locked and can not be replied to.