Runtime code modification. Erlang? No, Python
blog.ducksboard.com
blog.ducksboard.com
Since data in Erlang is immutable, you don't have to worry about what references will be left dangling. Since Erlang has no user-defined data types, you don't have to worry about redefining a class. (Big problem with Python reloading, all existing objects still belong to the old class instance.) Since Erlang is structured in terms of processes, and OTP can track which process is which thing, OTP has a defined mechanism for taking running server processes, examining their state, and allowing you to upgrade from old states to new states cleanly, and since in Erlang a process is basically nothing but its call stack and its current state, that upgrade is complete and relatively safe. You can literally upgrade a server mid-TCP connection without the client knowing.
Most languages, if poked properly, can change code at runtime. Even C can unload a dynamic library and load a new version of it at runtime. It's just that mutable values and poorly-defined boundaries between systems make it range from effectively impossible through "usable only as a desparate hack" (as seen here), Erlang makes it production-quality.
I say this only for educational purposes, not advocacy per se. I'd like to see further understanding of how Erlang works so that other language communities are more likely to pick up on the essential features of Erlang, instead of getting stuck on the superficial ones which is the usual case. (OTP is what you need to port, not "message passing"...)
So true.
"Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem."
http://www.flownet.com/gat/jpl-lisp.html
Since then, I always make sure I have a (safe) REPL backdoor into my long-running Perl apps.
Is it on CPAN?
- a controller action in Catalyst that listens at http://host/repl which evals the POST parameters. As a client, I use a simple admin-repl html page.
- in the main loop of a daemon script, a quick check for a row in a DB table or a special file in the server. When the server detects a new repl event, it evals the contents and writes the response back (either to the DB or to a file log).
- a 3 line AnyEvent::JSONRPC::Lite server that listens on a given local port for a string to eval. A matching JSONRPC client that calls that port with the repl string. I've used it to run scripts, and recently with a Corona-based Dancer app.
Maybe it could become a Plack::Middleware someday.
Recently, my team has been developing most of our newer network services using gevent. It's probably the closest thing to erlang that python has when it comes to programming asynchronous servers.
One of the things I always missed was this manhole feature, but while rummaging around the other day, I found this:
http://www.gevent.org/gevent.backdoor.html
Haven't tried it yet, but it looks like it will achieve the same task :)
I am just wondering how long would it take if the author and the Bad Engineer were different people.
Btw, it's still not the same as Erlang. So, I don't think the title is fare.
That being said, we are using reload() with manhole to update code. You just have to be extra careful and know what you're doing.
[1] http://twistedmatrix.com/documents/11.0.0/api/twisted.python...
In Erlang one could easily update any module, and re-importing modules is quite complicated in Python. Update will be seamless, too - old code will be running its last reductions (so already connected clients won't experience downtime) while new messages will be processed with a new code.
Surely, it is possible to achieve the same in Python, but that'd require a lot more code than monkey-patching several values.
Not to say that dynamically changing code at runtime is totally impossible in C - buffer overflow attacks do exactly that.