[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MirageOS-devel] Blog post on Irmin/CueKeeper

On 23 June 2015 at 15:48, Daniel BÃnzli <daniel.buenzli@xxxxxxxxxxxx> wrote:
> Le mardi, 23 juin 2015 Ã 13:24, Thomas Leonard a Ãcrit :
>> http://roscidus.com/blog/blog/2015/06/22/cuekeeper-internals-irmin/#problems-with-react
>> there is only one output (printf) and it is static (just for demonstration 
>> purposes).
> Ah yes sorry I couldn't read through the menagerie of operators and inline 
> definitions â a well (de)composed sequence of let bindings is easier for my 
> small brain.
>> The problem is with the non-outputting
>> (sprintf) S.map callback, which becomes slower and slower as more and
>> more instances of it run,
> Sure you are making a side-effect here (Thread.delay 1.0) that takes a lot of 
> time in an update that is meant to be instantaneous.

Note: the delay here is just to show the problem quickly, without
actually overloading my laptop. The real system doesn't sleep inside
the callbacks.

> Whenever the signal is switched it will still update until gc'd so all these 
> delay will still be performed (and accumulated). Signal definitions should be 
> effect free and reasonably quick so that they maintain the illusion of the 
> synchrony hypothesis.
>> and either runs out of memory (Javascript, with no weak refs) or
> Yes unfortunately you need to fallback to manual memory management which you 
> could do by replacing the S.bind by its `S.switch` ing definition and 
> introducing a gc'ing signal on the argument of the switch that strongly stops 
> the old signals whenever the higher-order signal changes:

Ah, I'd forgotten about switch (this is "join" in monad terminology, right?).

> let ss = S.map ~eq:(==) (function | 0 -> â) complete_actions
> let out = S.map (fun s -> Printfâ) (S.switch ss)
> let gc_ss = S.diff (fun _ old -> S.stop ~strong:true old) ss

I should probably replace most of the binds with this (being careful
that they don't return an existing signal, though).

>> crashes (due to a handler that isn't needed still getting called, now with 
>> an invalid input).
> Well I would argue that this is a problem of your program or your conceptual 
> view of signals. There is no such things as "a handler that isn't needed 
> still getting called"; that's a "callback" and effectful view of things but 
> that's not what the semantics of `S.map f s` tells you. `S.map f s` is a 
> signal such that for all point in time t after its creation you have [S.map f 
> s]_t = f [s]_t, and so `f` has to deal with this whatever `s` may become.

Can we define "A handler that isn't needed" as "A handler that would
be garbage collected if the GC ran now"?

(or, if we had a glabal sink, "A handler that isn't a dependency of
the global sink")

> Now of course you can argue that this is not what you want and that React 
> should be able to reason about the end time of signals but I'm not sure that 
> this would made things easier as it would certainly mean to fallback to 
> manually manage dependency among signals rather than let the natural 
> algebraic expressions of your program do so. But I'm open to better 
> suggestions.
> Best,
> Daniel

Dr Thomas Leonard        http://roscidus.com/blog/
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

MirageOS-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.