LiveNode Server

Andrew Kluthe andrew at ctech.me
Wed Apr 8 09:47:40 EDT 2015


To clarify just a little bit further. The code and objects weren't holding
onto memory, the variables used in that code were due to weird scoping. Big
chunks of db results, etc that persist after I've already done my business
with them and tried to move on.

If I can recommend a book on Javascript, I can't speak highly enough of the
insights given by  "JavsScript: the Good Parts" from O'Reilly. He provides
some history behind some of the design choices in javascript and some of
the problems still being worked around today in regards to the bad parts.

On Wed, Apr 8, 2015 at 8:41 AM Andrew Kluthe <andrew at ctech.me> wrote:

> I haven't had many problems with livecode chewing up memory and not
> letting it go (unless I've done something obvious like stash it someplace
> where I would expect it to persist). I think JS in general is prone to
> memory leaks just because of how much of it was designed around the use of
> global variables. All the scoping improvements we've had over the years
> were kind of grafted on top of this design to try and address this.
>
> In Livecode, memory leaks happen if you are really reckless.
>
> In most of the JS environments (node, browsers), they happen when you
> aren't careful.
>
> On Wed, Apr 8, 2015 at 4:54 AM David Bovill <david at viral.academy> wrote:
>
>> Thanks for this Andrew - I learned a lot. I spend a lot of time passing
>> messages around Livecode objects with a view to making them standalone
>> code
>> chunks. Debugging works pretty well - but there was a need for a library
>> and a graphing mechanism - design pattern style. This all adds overhead I
>> guess when it comes to just reading code, and the design patterns for
>> callbacks that closures seem to encourage makes this easier by itself?
>>
>> One thing that would be good to know more about with regard to Livecode is
>> the memory handling - so when does a peice of code get released from
>> memory? My understanding is that it does not - except possibly when the
>> stack it resides in is "deleted" from memory?
>>
>> Otherwise my understanding is that like with Hypercard the script is
>> compiled to bytecode the first time it is executed (which is a relatively
>> slow step), but thereafter resides in memory to be executed when needed.
>> Is
>> that about right?
>>
>> It makes me think of an architecture in Livecode using [[dispatch]] where
>> a
>> stack is loaded that contains the needed code should the dispatch call not
>> be handled by the message hierarchy - by default this stack could be
>> deleted after it is called - so releasing it from memory. Commonly called
>> handlers could be loaded before hand by a different command and therfore
>> stay in memory.
>>
>>
>> On 7 April 2015 at 21:21, Andrew Kluthe <andrew at ctech.me> wrote:
>>
>> > >>1. Livecode messaging is fully asynchronous. Not semi-async.
>> >
>> > Right, when I said semi-async I was referring to the single
>> threadedness of
>> > livecode (which node shares) along with all the baked into livecode
>> stuff
>> > that blocks up messages currently: accessing a large file on disk,
>> posting
>> > some information to a web service with a large json payload being
>> returned.
>> > It's async, with some pretty hard to work around exceptions (url library
>> > specifically has been the primary source of past frustration in this
>> way).
>> >
>> > >>3. Livecode does not have closures = passing anonymous callbacks as
>> > params to functions so they can be executed later
>> >
>> > As for anonymous callbacks, I totally agree. Most early Node development
>> > had to overcome the callback hell that these patterns introduce.
>> However,
>> > almost all of the nodejs projects and libraries I've worked with
>> leveraged
>> > them heavily or exclusively. Promsies seem to have become the standard
>> way
>> > of dealing with the callback hell that node was so famous for for a long
>> > time. Why does node use anonymous functions over the method you linked
>> to
>> > in the article? Anonymous functions are marked for garbage collection
>> > immediately after being returned. All other functions at the global
>> scope
>> > run the risk of needlessly using memory after they run. I've gotten into
>> > some hairy situations with memory management with these kinds of named
>> > callbacks (specifically for database access and return of lots of
>> results
>> > when not scoped correctly).
>> >
>> > Passing a function (not just a name of a function to be used with a
>> send or
>> > a dispatch later on) as a parameter even in your article still
>> demonstrates
>> > something LC just can't do currently. In the article he's still using
>> > closures, it's just got a name instead of being anonymous. It's still a
>> > closure. LC has ways to accomplish similar things by passing names of
>> > functions and using dispatch, but I think it's not exactly the same.
>> > Closures are part of the reason node.js works the way it does and
>> closures
>> > are one of the pirmary reasons javascript was chosen for node. It's
>> > certainly possible to do async without them, but closures are what
>> makes it
>> > easy and kind of a fundamental principle to working in node.js.
>> >
>> > >>4. But we can easily call / dispatch calls to functions by passing
>> names
>> > around and we can limit scope by using private handlers or libraries.
>> >
>> > Sure, there is nothing STOPPING us from implementing named callbacks in
>> the
>> > current fashion or passing the named callback references dynamically as
>> you
>> > and I mentioned, but from experience trying it this way I feel like it
>> > makes maintaining large projects built this way a lot more difficult. To
>> > the point where I ended up completely redoing most of the livecode stuff
>> > I've written in this way early on because it was getting to be a
>> nightmare
>> > to maintain a completely separate callback functions rather than the
>> sort
>> > of nested structure you get in node with callbacks. It takes a lot of
>> > discipline in placement and grouping of the code that is related in this
>> > way to come back later and make sense of it. In summary: it can be done,
>> > but that doesn't mean that it SHOULD be done.
>> >
>> > Kind of a weird long post there. Sorry for the length and probable
>> > repetition of my points.
>> >
>> >
>> > Also, this was something really neat I've used recently to make node
>> work
>> > in-process with some .NET applications we have. Something that does this
>> > with node and LC would indeed be the bees knees.
>> >
>> >
>> > http://www.hanselman.com/blog/ItsJustASoftwareIssueEdgejsBri
>> ngsNodeAndNETTogetherOnThreePlatforms.aspx
>> >
>> > Specifically the part about it allowing us to write node extensions in
>> C#
>> > in addition to the standard C and C++ way of doing it. I'd love to be
>> able
>> > to hook node into extensions written in livecode.
>> >
>> >
>> > On Tue, Apr 7, 2015 at 12:24 PM Richard Gaskin <
>> ambassador at fourthworld.com
>> > >
>> > wrote:
>> >
>> > > David Bovill wrote:
>> > >
>> > >  > OK. A few questions... I'll post them as assertions to aid clarity.
>> > >
>> > > Personally I find it clearer to read questions as questions, but with
>> > > that explanation I can work with this:
>> > >
>> > >  >   1. Livecode messaging is fully asynchronous. Not semi-async.
>> > >
>> > > What is "semi-asynchronous" in the context of LC?
>> > >
>> > > There is a distinction between "asynchronous" and "non-blocking" that
>> > > I'm not entirely clear on, so I'll use "non-blocking" for now:
>> > >
>> > > Socket I/O messaging can be non-blocking when the "with <message>"
>> > > option is used, e.g.:
>> > >
>> > >     accept connections on port 8888 with message "GotConnection"
>> > >
>> > > But this is of limited value within a single LC instance, since doing
>> > > anything with that message is likely going to involve blocking code
>> > > (e.g., reading a file or accessing a database, doing something with
>> that
>> > > data, and then returning it).
>> > >
>> > > So messages will keep coming in, but they'll queue up.  This may be
>> fine
>> > > for light loads, but when expecting multiple simultaneous connections
>> it
>> > > would be ideal to handle the tasks more independently.
>> > >
>> > > Many programs do this with threading, but we don't have threading in
>> LC.
>> > >
>> > > Instead of multithreading we can use multiprocessing, having multiple
>> > > instances of LC apps each working on a separate task.
>> > >
>> > > The challenge is that to hand off a socket request to a child process
>> > > entirely would require us to have some way of handing over the socket
>> > > connection itself.  I believe fork allows this, but I know of no way
>> to
>> > > launch new instances of an LC app in a way that will hand over the
>> > > socket connection to them.
>> > >
>> > > In lieu of being able to fork, two options I know of are the ones I
>> > > noted earlier; others may be possible as well, but these seem common
>> > > enough to be reasonable starting points:
>> > > <http://lists.runrev.com/pipermail/use-livecode/2015-April/
>> 213208.html>
>> > >
>> > >
>> > >
>> > >  >   2. There are a bunch of functions that are currently synchronous
>> in
>> > >  > LiveCode that make it difficult to create asynchronous code - such
>> as
>> > >  > certain network call like POST.
>> > >
>> > > Yes, as above.
>> > >
>> > >
>> > >  >   3. Livecode does not have closures = passing anonymous callbacks
>> as
>> > >  > params to functions so they can be executed later
>> > >
>> > > Not per se, but as you note:
>> > >
>> > >  >   4. But we can easily call / dispatch calls to functions by
>> passing
>> > >  > names around and we can limit scope by using private handlers or
>> > >  > libraries.
>> > >  >
>> > >  > Here is an article about why you should not use anonymous callbacks
>> > >  > that seems interesting in the context of readabiity and literate
>> > >  > programming languages:
>> > >  >
>> > >  >   * Avoiding anonymous JavaScript functions
>> > >  > http://toddmotto.com/avoiding-anonymous-javascript-functions/
>> > >
>> > > Good find.  While most of that is very JS-specific, the
>> > > readability/complexity argument applies in LC well.  As a general
>> rule,
>> > > I feel that "do" is a last resort when all more direct means of
>> > > accomplishing something have been exhausted, and even "dispatch",
>> > > "send", and "value" can have similar impact in terms of
>> > > debugging/maintenance.
>> > >
>> > > I almost never use "do" anywhere, and on servers I limit use of the
>> > > others for another reason not mentioned in the article, security:
>> since
>> > > they execute arbitrary code by design, "do", "dispatch", "send" and
>> > > "value" can potentially be sources of injection when used on any part
>> of
>> > > incoming data.
>> > >
>> > > I use "dispatch" in one place in my server framework, but only after
>> > > checking an incoming command argument against a list of known one-word
>> > > commands; any request missing a command parameter, or having one not
>> > > found on that list, returns an "invalid command" error message.
>> > >
>> > > --
>> > >   Richard Gaskin
>> > >   Fourth World Systems
>> > >   Software Design and Development for the Desktop, Mobile, and the Web
>> > >   ____________________________________________________________
>> ________
>> > >   Ambassador at FourthWorld.com
>> http://www.FourthWorld.com
>> > >
>> > > _______________________________________________
>> > > use-livecode mailing list
>> > > use-livecode at lists.runrev.com
>> > > Please visit this url to subscribe, unsubscribe and manage your
>> > > subscription preferences:
>> > > http://lists.runrev.com/mailman/listinfo/use-livecode
>> > >
>> > _______________________________________________
>> > use-livecode mailing list
>> > use-livecode at lists.runrev.com
>> > Please visit this url to subscribe, unsubscribe and manage your
>> > subscription preferences:
>> > http://lists.runrev.com/mailman/listinfo/use-livecode
>> >
>> _______________________________________________
>> use-livecode mailing list
>> use-livecode at lists.runrev.com
>> Please visit this url to subscribe, unsubscribe and manage your
>> subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
>>
>



More information about the Use-livecode mailing list