Hi, is there a way to get a fresh session or instance of ABCL, short of reloading all the classes? Ideally I'd like to be able to have two or more instances which exist at the same time and are independent of each other.
I believe the answer to this question is "no", but I just want to make sure I am not overlooking something. If indeed it's not possible now, what would it take to make it happen? I see there is a certain amount of static data -- would it be necessary to replace that with (just for the sake of discussion) a hash table which takes a session or instance id as a key?
Any thoughts on this topic will be appreciated.
best,
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Dec 9, 2014, at 23:06, Robert Dodier robert.dodier@gmail.com wrote:
Hi, is there a way to get a fresh session or instance of ABCL, short of reloading all the classes? Ideally I'd like to be able to have two or more instances which exist at the same time and are independent of each other.
The Lisp environment is a global singleton per JVM process, like that of any other Lisp implementation is per OS process. So, to get a fresh instance, one would need to start multiple JVMs, just like one would have to start multiple instances of, say, SBCL to get a “fresh session”. Since starting JVMs can be expensive time-wise, the Java ecology has developed numerous “drop-in” tools to pre-initialize JVMs, of which the best known may be [drip][].
[drip]: https://github.com/flatland/drip
I believe the answer to this question is "no", but I just want to make sure I am not overlooking something. If indeed it's not possible now, what would it take to make it happen? I see there is a certain amount of static data -- would it be necessary to replace that with (just for the sake of discussion) a hash table which takes a session or instance id as a key?
Any thoughts on this topic will be appreciated.
To carry forward the comparison with SBCL: what would it take to make SBCL have a “fresh instance”? Maybe you don’t really want a “fresh instance” in ABCL down to its initial state but some equivalent of save-image-and-die restoration? Unfortunately, I know of no mechanism in the Oracle-derived JVMs that allow one to use mmap()-like facilities to load in a previously dumped JVM instance. I think that there once were commercial, non-free JVM implementations available that would do this sort of thing (Terracotta?), but I can’t find any mention of one in a quick web search.
Could you be more specific about your use case?
On 2014-12-10, Mark Evenson evenson@panix.com wrote:
The Lisp environment is a global singleton per JVM process, like that of any other Lisp implementation is per OS process.
Hmm, I wonder if it's possible to use multiple classloaders to get separate ABCL environments ...
To carry forward the comparison with SBCL: what would it take to make SBCL have a “fresh instance”?
SBCL has some POSIX functions, including fork, which makes possible the conventional Unixy client/server model. I'm not trying to create exactly that functionality for ABCL but it is not too far off.
Could you be more specific about your use case?
Well, I am loading ABCL and then Maxima into a Jetty servlet. The servlet class exposes a few methods which call Maxima functions to provide some services to Flex clients; BlazeDS is the glue. I'd like to figure out a way to ensure that different browser sessions don't step on each others toes. Maxima itself doesn't have any way to do that.
best,
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Wed, Dec 10, 2014 at 7:02 PM, Robert Dodier robert.dodier@gmail.com wrote:
On 2014-12-10, Mark Evenson evenson@panix.com wrote:
The Lisp environment is a global singleton per JVM process, like that of any other Lisp implementation is per OS process.
Hmm, I wonder if it's possible to use multiple classloaders to get separate ABCL environments ...
Yes, it's possible. You just have to be careful and avoid sharing any ABCL-related class among classloaders through a common ancestor. I.e. you have to load ABCL from a location unknown to the JVM (not from CLASSPATH nor the webapp's libs, etc.).
To carry forward the comparison with SBCL: what would it take to make SBCL have a “fresh instance”?
SBCL has some POSIX functions, including fork, which makes possible the conventional Unixy client/server model. I'm not trying to create exactly that functionality for ABCL but it is not too far off.
fork() has an important difference: it allows some state to be shared, at the discretion of the programmer - things start to diverge only from fork() onwards. With separate classloaders, in general you either have total sharing or total isolation, no middle ground (unless you introduce message buses or other means of communication, but then you're moving away from the fork() model, as far as I know it, which is very little).
Could you be more specific about your use case?
Well, I am loading ABCL and then Maxima into a Jetty servlet. The servlet class exposes a few methods which call Maxima functions to provide some services to Flex clients; BlazeDS is the glue. I'd like to figure out a way to ensure that different browser sessions don't step on each others toes. Maxima itself doesn't have any way to do that.
Define "step on each other's toes". Do you mean redefining things? Access to global variables? Or that simply evaluating an arbitrary Maxima form has potential concurrency issues? Would simply loading Maxima in different Lisp packages work and be enough for you? In general, one ABCL instance per HTTP session doesn't seem a very smart thing to do. It is smarter than one full JVM per session, but not terribly so. Alas, maybe you cannot avoid it. You'll probably want to pool instances so as to have a fresh one ready when you need it and not incur in startup time costs.
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On 10 Dec 2014, at 21:13, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Dec 10, 2014 at 7:02 PM, Robert Dodier robert.dodier@gmail.com wrote: On 2014-12-10, Mark Evenson evenson@panix.com wrote:
The Lisp environment is a global singleton per JVM process, like that of any other Lisp implementation is per OS process.
Hmm, I wonder if it's possible to use multiple classloaders to get separate ABCL environments ...
Yes, it's possible. You just have to be careful and avoid sharing any ABCL-related class among classloaders through a common ancestor. I.e. you have to load ABCL from a location unknown to the JVM (not from CLASSPATH nor the webapp's libs, etc.).
[…]
Upon reflection, I think this abstraction of “multiple ABCL instances”, if improved, could help address some long standing problems with the ABCL implementation if we used this to, say actually go “back in time” to a given stack frame. Need to think more…
On 2015-01-26, Mark Evenson evenson@panix.com wrote:
Upon reflection, I think this abstraction of “multiple ABCL instances”, if improved, could help address some long standing problems with the ABCL implementation if we used this to, say actually go “back in time” to a given stack frame. Need to think more…
My own interest in this question was inspired by a desire to get something like the functionality of Un*x fork, namely to create independent instances without having to start a new process and load all the classes. It seems that "all" one has to do (scare quotes since of course it's no easy task) is to identify all the static data and replace it with a table of instance data. The table presumably starts with a single instance and additional instances could be created by copying existing instances or creating them ex nihilo. I was thinking about how to create handlers for web services in a way that prevents them from stepping on each others toes.
Such a feature could be used to implement a roll-back function -- one would copy an instance and then continue to evaluate stuff in one copy; to roll back would mean nuking the copy and going back to the original. Just thinking out loud here.
Anyway in a sense this is an "easy" (Java-only) programming problem; no enlightenment (i.e. comprehension of CLHS) required. 8^)
best,
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On 2014-12-10, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Dec 10, 2014 at 7:02 PM, Robert Dodier robert.dodier@gmail.com
Well, I am loading ABCL and then Maxima into a Jetty servlet. The servlet class exposes a few methods which call Maxima functions to provide some services to Flex clients; BlazeDS is the glue. I'd like to figure out a way to ensure that different browser sessions don't step on each others toes. Maxima itself doesn't have any way to do that.
Define "step on each other's toes".
Well, Maxima has a lot of global state (options, variables with values, user-defined functions, etc etc). Ideally from one session you wouldn't have any visibility into another sessions global state.
Would simply loading Maxima in different Lisp packages work and be enough for you?
Not sure what you mean. Can you clarify?
In general, one ABCL instance per HTTP session doesn't seem a very smart thing to do.
It would be enough to make one copy of the static data in ABCL classes per session ... I don't suppose that's possible, except maybe by some heavy-duty JVM hacking.
best
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Wed, Dec 10, 2014 at 10:37 PM, Robert Dodier robert.dodier@gmail.com wrote:
On 2014-12-10, Alessio Stalla alessiostalla@gmail.com wrote:
On Wed, Dec 10, 2014 at 7:02 PM, Robert Dodier robert.dodier@gmail.com
Well, I am loading ABCL and then Maxima into a Jetty servlet. The servlet class exposes a few methods which call Maxima functions to provide some services to Flex clients; BlazeDS is the glue. I'd like to figure out a way to ensure that different browser sessions don't step on each others toes. Maxima itself doesn't have any way to do that.
Define "step on each other's toes".
Well, Maxima has a lot of global state (options, variables with values, user-defined functions, etc etc). Ideally from one session you wouldn't have any visibility into another sessions global state.
Ok, I was thinking - if the API surface exposed to the web is small, and you don't have the entire Maxima language at your disposal but just a few functions, it may make more sense to just isolate those functions (e.g. by rebinding all the global variables they access).
Would simply loading Maxima in different Lisp packages work and be
enough for you?
Not sure what you mean. Can you clarify?
I mean, if shared state is only in the form of variables inside Maxima (not global Lisp stuff like variables in the common-lisp package, the MOP etc.), then
(defpackage :maxima ...) (load-everything-maxima) (rename-package :maxima :maxima-session-1234)
would give you a new Maxima instance in the same Lisp image. You would have to manually (delete-package :maxima-session-1234) after use and everything would have to be designed so as no references to symbols in :maxima-session-1234 leak outside it. So there are a few strong assumptions here that might not hold for Maxima, but if they do, the solution is relatively trivial.
In general, one ABCL instance per HTTP session doesn't seem a very smart thing to do.
It would be enough to make one copy of the static data in ABCL classes per session ... I don't suppose that's possible, except maybe by some heavy-duty JVM hacking.
It might be possible, but I don't think it would buy you much. Unless there's some Oracle internal API I don't know of, copying stuff in the JVM is entirely a user-space thing - you'd have to walk the object graph recursively and copy stuff yourself, with a lot of special casing to boot. What little you might save in performance you'd pay tenfold in headaches. Better to invest in pooling ClassLoaders. But actually, I would go with multiple JVMs. You'll definitely waste more resources, but you'll be sure to be safe from unexpected issues.
best
Robert Dodier
Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On 2014-12-10, Alessio Stalla alessiostalla@gmail.com wrote:
I mean, if shared state is only in the form of variables inside Maxima (not global Lisp stuff like variables in the common-lisp package, the MOP etc.), then
(defpackage :maxima ...) (load-everything-maxima) (rename-package :maxima :maxima-session-1234)
would give you a new Maxima instance in the same Lisp image.
Hmm, this seems a little problematic for Maxima. There are a number of explicit references to the package :maxima so those can't be resolved after the package is renamed. Is there any way to automatically redirect those references to the renamed package?
I could at least create a per-session package and put the sessions's functions, variables, etc into that. It wouldn't help with global state, but at least the per-session states wouldn't overlap.
best,
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On 2014-12-10, Alessio Stalla alessiostalla@gmail.com wrote:
I mean, if shared state is only in the form of variables inside Maxima (not global Lisp stuff like variables in the common-lisp package, the MOP etc.), then
(defpackage :maxima ...) (load-everything-maxima) (rename-package :maxima :maxima-session-1234)
would give you a new Maxima instance in the same Lisp image.
Hmm, that's a good idea. I think that will work for Maxima. I'll give it a try.
best
Robert Dodier
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://mailman.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
armedbear-devel@common-lisp.net