Hacker News new | past | comments | ask | show | jobs | submit login
So you want to live-reload Rust (2020) (fasterthanli.me)
25 points by sea6ear 13 days ago | hide | past | favorite | 6 comments

This is about reloading dynlibs, technically cool I guess, but maybe asking for trouble. I prefer to launch a new process, then transfer any open connections and fd's with the SCM_RIGHTS auxiliary message under Linux.

I once asked Joe Armstrong (RIP) about Erlang's famous hot reload feature compared to doing something like that, and he agreed with me that hot reload wasn't really worthwhile, as sexy as it might sound.

Nice. New process definitely sounds cleaner if it supports what your program does, but I think if you have open GUI windows or GPU contexts you want to keep around, the dylib route might be your only option.

I don't know about GPU contexts: is there no way to hand them off? Reliable hot reload is always painful no matter how you do it. I don't know the situation with gpu contexts but if your long running program needs hot reloads and has a gui, maybe you want to split the gui itself into a separate process, or alternatively maybe do that with the component requiring reload.

The most common reason to want this is for long running programs with a plug-in architecture. Here’s my advice, for use cases where the plug-in and the plug-in loader are both under your control:

1. Don’t directly dlopen the .so file. Copy it to a temporary file and dlopen that. Much fewer headaches that way when the original .so file changes. Bonus points for using Linux’s memfd or FreeBSD’s SHM_ANON.

2. Rely as little on global/thread-local state as possible in the plug-in. Minimize the use of non-reentrant function calls in exported functions.

3. Don’t use musl. Its dlclose is a no-op and will cause memory leaks.

4. If the plug-in is to be accessed across multiple threads, copy the symbols you’ll need from the plug-in into a struct, and maintain a reference count alongside the struct. When reloading the plug-in, create a new struct for all new threads to use, and free the old struct when its reference count goes to zero.

Another excellent article from Amos digging into the minutiae of how executables work!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact