If I have a ruby script Daemon that, as it's name implies, runs as a daemon, monitoring parts of the system and able to perform commands which require authentication, for example changing permissions, is there an easy way to have a second ruby script, say client, communicate to that script and send it commands / ask for information? I'm looking for a built in ruby way of doing this, I'd prefer to avoid building my own server protocol here.
Ruby provides many mechanisms for this including your standards such as: sockets, pipes, shared memory. But ruby also has a higher level library specifically for IPC which you can checkout Here, Drb. I haven't had a chance to play around with it too much but it looks really cool.
You may want to look into http://rubyeventmachine.com/
Related
I need to do something relatively simple, and I don't really want to install a MOM like RabittMQ etc.
There are several programs that "register" with a central
"service" server through TCP. The only function of the server is to
call back all the registered clients when they all in turn say
"DONE". So it is a kind of "join" (edit: Barrier) for distributed client processes.
When all clients say "DONE" (they can be done at totally different times), the central server messages
them all saying "ALL-COMPLETE". The clients "block" until asynchronously called back.
So this is a kind of distributed asynchronous Observer Pattern. The server has to keep track of where the clients are somehow. It is ok for the client to pass its IP address to the server etc. It is constructable with things like Boost::Signal, BOOST::Asio, BOOST::Dataflow etc, but I don't want to reinvent the wheel if something simple already exists. I got very close with ZeroMQ, but non of their patterns support this use-case very well, AFAIK.
Is there a very simple system that does this? Notice that the server can be written in any language. I just need C++ bindings for the clients.
After much searching, I used this library
https://github.com/actor-framework
It turns out that doing this with this framework is relatively straightforward. The only real "impediment" to using it is that the library seems to have gotten an API transition recently and the documentation .pdf file has not completely caught up with the source. No biggie since the example programs and the source (.hpp) files get you over this hump. However, they need to bring the docs in sync with the source. In addition, IMO they need to provide more interesting examples on how to use c++ Actors for extreme performance. For my case it is not needed, but the idea of actors (shared nothing) in this use-case is one of the reasons people use it instead shared memory communication when using threads.
Also, getting used to the syntax that the library enforces (get used to lambdas!) if one is not used to state of the art c++11 programs it can be a bit of a mind-twister at first. Then, the triviality of remembering all the clients that registered with the server was the only other caveat.
STRONGLY RECOMMENDED.
I was trying to create my website using CGI and ERB, but when I search on the web, I see people saying I should always avoid using CGI, and always use Rack.
I understand CGI will fork a lot of Ruby processes, but if I use FastCGI, only one persistent process will be created, and it is adopted by PHP websites too. Plus FastCGI interface only create one object for one request and has very good performance, as opposed to Rack which creates 7 objects at once.
Is there any specific reason I should not use CGI? Or it is just false assumption and it is entirely ok to use CGI/FastCGI?
CGI, by which I mean both the interface and the common programming libraries and practices around it, was written in a different time. It has a view of request handlers as distinct processes connected to the webserver via environment variables and standard I/O streams.
This was state-of-the-art in its day, when there were not really "web frameworks" and "embedded server modules" as we think of them today. Thus...
CGI tends to be slow
Again, the CGI model spawns one new process per connection. While spawning processes per se is cheap these days, heavy web app initialization — reading and parsing scores of modules, making database connections, etc. — makes this quite expensive.
CGI tends toward too-low-level (IMHO) design
Again, the CGI model explicitly mentions environment variables and standard input as the interface between request and handler. But ... who cares? That's much lower level than the app designer should generally be thinking about. If you look at libraries and code based on CGI, you'll see that the bulk of it encourages "business logic" right alongside form parsing and HTML generation, which is now widely seen as a dangerous mixing of concerns.
Contrast with something like Rack::Builder, where right away the coder is thinking of mapping a namespace to an action, and what that means for the broader web application. (Suddenly we are free to argue about the semantic web and the virtues of REST and this and that, because we're not thinking about generating radio buttons based off user-supplied input.)
Yes, something like Rack::Builder could be implemented on top of CGI, but, that's the point. It'd have to be a layer of abstraction built on top of CGI.
CGI tends to be sneeringly dismissed
Despite CGI working perfectly well within its limitations, despite it being simple and widely understood, CGI is often dismissed out of hand. You, too, might be dismissed out of hand if CGI is all you know.
Don't use CGI. Please. It's not worth it. Back in the 1990s when nobody knew better it seemed like a good idea, but that was when scripts were infrequent, used for special cases like handling form submissions, not driving entire sites.
FastCGI is an attempt at a "better CGI" but it's still deficient in a large number of ways, especially because you have to manage your FastCGI worker processes.
Rack is a much better system, and it works very well. If you use Rack, you have a wide variety of hosting systems to choose from, even Passenger which is really simple and reliable.
I don't know what mean when you say Rack creates "7 objects at once" unless you mean there are 7 different Rack processes running somehow or you've made a mistake in your implementation.
I can't think of a single instance where CGI would be better than a Rack equivalent.
There exists a lot of confusion about what CGI, Rack etc. really are. As I describe here, Rack is an API, and FastCGI is a protocol. CGI is also a protocol, but in its narrow sense also an implementation, and for what you're speaking of is not at all the same thing as FastCGI. So let's start with the background.
Back in the early 90s, web servers simply read files (HTML, images, whatever) off the disk and sent them to the client. People started to want to do some processing at the time of the request, and the early solution that came out was to run a program that would produce the result sent back to the client, rather than just reading the file. The "protocol" for this was for the web server to be given a URL that it was configured to execute as a program (e.g., /cgi-bin/my-script), where the web server would then set up a set of environment variables with various information about the request and run the program with the body of the request on the standard input. This was referred to as the "Common Gateway Interface."
Given that this forks off a new process for every request, it's clearly inefficient, and you almost certainly don't want to use this style of dynamic request handling on high-volume web sites. (Starting a whole new process is relatively expensive in computational resources.)
One solution to making this more efficient is to, rather than starting a new process, send the request information to an existing process that's already running. This is what FastCGI is all about; it maintains a very similar interface to CGI (you have a set of variables with most of the request information, and a stream of data for the body of the request). But instead of setting actual Unix environment variables and starting a new process with the body on stdin, it sends a request similar to an HTTP request to an FCGI server already running on the machine where it specifies the values of these variables and the request body contents.
If the web server can have the program code embedded in it somehow, this becomes even more efficient because it just runs the code itself. Two classic examples of how you might do this would be:
Have PHP embedded in Apache, so that the "Apache server code" just calls the "PHP server code" that's part of the same process; and
Not run Apache at all, but have the web server be written in Ruby (or Python, or whatever) and load and run more Ruby code that's been custom-written to handle the request.
So where does Rack come in to this? Rack is an API that lets code that handles web requests receive it in a common way, regardless of the web server. So given some Ruby code to process a request that uses the Rack API, the web server might:
Be a Ruby web server that simply makes function calls in its own process to the Rack-compliant code that it loaded;
Be a web server (written in any language) that uses the FastCGI protocol to talk to another process with FastCGI server code that, again, makes function calls to the Rack-compliant code that handles the request; or
Be a server that starts a brand new process that interprets the CGI environment variables and standard input passed to it and then calls the Rack-compliant code.
So whether you're using CGI, FastCGI, another inter-process protocol, or an intra-process protocol, makes no difference; you can do any of those using Rack so long as the server knows about it or is talking to a process that can understand CGI, FastCGI or whatever and call Rack-compliant code based on that request.
So:
For performance scaling, you definitely don't want to be using CGI; you want to be using FastCGI, a similar protocol (such as the Tomcat one), or direct in-process calling of the code.
If you use the Rack API, you don't need to worry at the early stages which protocol you're using between your web server and your program because the whole point of APIs like Rack is that you can change it later.
I'm looking into building a service to run in the background that allows clients to connect and send commands, and get data back. I'm planning on writing the service in Ruby (as a gem) but wanted to know what the best method would be to allow clients to connect to the API?
I figured a socket connection would make sense, like you'd connect with Redis or something, but I'm not sure where to start!
Any tips would be much appreciated :)
Yep, you're on the right path. A socket is just a bidirectional communication channel that allows two programs to exchange bytes. If both endpoints are on the same machine, UNIX sockets are the obvious choice; otherwise, you'll need a TCP socket to communicate over the network. The principle is the same in either case.
On top of the socket, you'll have to define your own protocol, or you could use an existing one (such as HTTP) if it applies to your situation.
A random sockets tutorial.
Since you ask for any tips, my advice to you is that building a service container is hard work. Since you don't actually need to, there being lots of awesome service containers already, you should probably use one of those.
I would recommend something behind HTTP, which gives you a whole lot of advantages around existing tooling, message framing, content negotiation, scaling your service, and deployment and upgrade models.
If you want to avoid external dependencies, using something like Webrick or Mongel that is pure Ruby is a fine way to avoid needing to wrap Apache or Nginx around your system.
This also allows you to separate out the concerns in your project: work on building the actual service layer first, handling commands and returning responses. Run that under any web server, and get it going.
Then when you have time, focus separately on how to build the service container to meet your needs: because you know that the underlying service layer works fine, you can focus on only solving the container problems.
If you really do want to build your own container, I strongly recommend you use something higher level than a socket. Tools like 0mq provide framing and other message layer features that you don't get from a socket, and make it much easier to focus on defining the interesting parts of your problem space - the commands - rather than low level details like parsing a wire format and protocol.
I'm using a Ruby/Rails app with Redis running in the background on an EC2 server (Amazon Web Services AWS). This is the ubuntu build I found to be easiest to work with:
Linux version 2.6.32-341-ec2 (buildd#crested) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #42-Ubuntu SMP Tue Dec 6 14:56:13 UTC 2011
In my main .rb file that does most of the polling/searching I have this rubygems required, you should definitely check them out:
require 'aws'
require 'redis'
require 'timeout'
require 'json'
Let me know what you are specifically trying to do if that doesn't help you enough. Good luck!
I've built a couple of daemons with EventMachine in the past. It is efficient and powerful, supports TCP, HTTP and everything else. People even write web servers on top of it.
Is there a module for Ruby that makes it easy to share objects between multiple processes? I'm looking for something similar to Python's multiprocessing, which supports process-safe queues and pipes that can be shared between processes.
I think you can do a lot of what you want using the facilities of Ruby IO; you're sharing between processes, not threads, correct?
If that's the case, IO.pipe will do what you need. Ruby doesn't have any built-in way of handling cross-process queues (to my knowledge), but you can also use FIFOs (if you're on Unix).
If you want something more fine-grained, and with good threading support, I'm fairly certain that you can piggyback on java.util.concurrent if you use JRuby. MRI has pretty lousy threading/concurrency support, so if that's what your aiming for, JRuby is probably a better place to go.
I've run into this library but I haven't tried it yet.
Parallel::ForkManager — A simple parallel processing fork manager.
http://parallelforkmgr.rubyforge.org/
Combining DRb, which provides simple inter-process communication, with Queue or SizedQueue, which are both threadsafe queues, should give you what you need.
You may also want to check out beanstalkd which is also hosted on github
I'm looking to start a MUD client application, which connects to a MUD hosted on a telnet server. The only thing important to me is that it runs painlessly and efficiently across any OS. Aside from that requirement, I'm not really sold on any language.
So I'm looking for a freely available telnet client library on which I can base my application, so I don't have to deal with the details of the protocol too much.
I would always consider Twisted for this kind of thing (Python).
The beauty is that if you later decide to swap it out to SSH or anything more secure than telnet, you can with little pain.
Twisted, twisted, twisted!
To use telnet, see package twisted.conch.telnet. It's got some spartan API docs, but the real information on using it comes from searching on Google Code Search, such as this nugget from grailmud - a MUD server.
For all of my MUD programming, I just created my own routines from the ground up using the RFCs.
In case you'd like to avoid some of my pain, I wrapped it up into a fairly simple C# class that handles Telnet properly. In case you'd like to peruse it, you can view it here.
This code has been copy/pasted and run on Windows and on Linux (through Mono) on a handful of separate projects and works pretty good.
There is a telnet interface in CPAN if you like Perl. It's pretty minimal, but it should get the job done.
[edit]
libcurl is also supposed to be able to do telnet, although I couldn't find any examples of it.
pmc ( http://sourceforge.net/projects/perlmudclient/ ) was an attempt to do exactly this. I've spent some of the last week going through it; it uses an older modified version of Net::Telnet to do its connectivity work.
My problem is that Net::Telnet seems to have a blocking interface when a partial line is sent by the server, i.e. a line not terminated by a newline. It has two features that support this (waitfor and its prompt mechanism), because almost all telnet servers have prompts that are not newline-terminated.
MUDs often have "prompts" that are non-standard and vary through the course of the game; the MUD I admin on has a "Your choice: " prompt as its login [it's not just for usernames], and many game features present alternative prompts. So I suspect you'll need to bear this in mind when you go looking for a cross-platform Telnet library!
If you like C, I heartily recommend libtelnet. It will maintain an internal state that does all the IAC sequence parsing for you, and handles option negotiation using the Q method.