Fork me on GitHub
#reagent
<
2015-09-02
>
martinklepsch20:09:59

When queueing things in an inactive tab with re-frame’s dispatch I need to first focus the window or at least make parts of it visible again before the handler fires — is there a way to mitigate this?

martinklepsch20:09:36

I tried dispatch-sync without much of a difference

darwin20:09:24

@martinklepsch: re-frame’s core async queue of events is stopped or reagent’s rendering? I would guess the later

darwin20:09:41

it uses requestAnimationFrame which gets paused in inactive tabs in some browsers

martinklepsch20:09:08

It’s definitely also re-frame’s queue. Rendering too I believe but that’s not bothering me for now.

darwin20:09:12

AFAIK re-frame uses setTimeout, which could slow-down your event queue if tab is inactive, but not stop it

martinklepsch20:09:38

This is in an electron app fwiw. Sending a notification using a re-frame handler on a fs.watch event. When I add the plain (js/Notification. …) call to the watch callback it immediately triggers a notification

darwin20:09:59

setTimeout/setInterval could be throttled to 1 event per second if tab is inactive, according to this: http://stackoverflow.com/questions/15871942/how-do-browsers-pause-change-javascript-when-tab-or-window-is-not-active

darwin20:09:00

so if you expect fs.watch to post many events… this is not the way to go, I guess

martinklepsch20:09:14

it’s a low-frequency event. The handler is immediately ran if the window is even only partially visible. OS X Expose or moving a window that’s covering out of the way is enough

darwin20:09:50

ok, then it is maybe an electron optimization thing

darwin20:09:35

I recall a discussion, someone wanted to improve re-frame’s queue throughput by using https://code.google.com/p/closure-library/source/browse/closure/goog/async/nexttick.js

darwin20:09:49

instead of setTimeout 0

darwin20:09:03

anyways, you can start by commenting out that setTimeout in re-frame’s code

darwin21:09:22

maybe it is problem of core.async itself, internally it might do setTimeout too, I’m not familiar with its internals

mikethompson21:09:03

@martinklepsch: just to state the obvious, the "problem" with background tabs is that they are throttled. For example, the "annimationFrames" are not happening every 16ms. You might be lucky to have one per second, probably less. In its main event loop, re-frame goes to some trouble to "hand back control" to the browser, to make sure it doesn't "Hog the CPU" .... the trouble with that approach is that it can take a long time to get an event handled when the app is in a throttled background tab

mikethompson21:09:06

re-frame is nicely handing back control the browser, and then the browser, because of throttling, in not then giving it back for a veeeeeeeery long time.

mikethompson21:09:30

So the handling of the (dispatch [xxx]) takes a while.

martinklepsch21:09:41

@mikethompson: is there some maximum you’d say it takes?

mikethompson21:09:23

@martinklepsch: I've never measured it

martinklepsch21:09:29

I read the CPU Hogging wiki page and I think here it takes longer than what could be considered normal. (waiting for it since I started typing this ~20s)

martinklepsch21:09:48

And now I got it.

mikethompson21:09:50

@martinklepsch: but dispatch-sync has no queue, it just happens

mikethompson21:09:23

By that, I mean the handler just runs.

mikethompson21:09:55

Any screen updates that arise from the event handler running will be handled by an anninmationFrame.

mikethompson21:09:10

And, if things are throttled, that could take a while.

mikethompson21:09:57

Question: is the problem the "handling of the event" or is the problem the speed with which the window subsequently updates. I'm getting the impression that your event handler is calling a fucntion in the electron API. What does that function do?

mikethompson21:09:14

Sorry, I've read back. I can now see what you said before. You have an fs.watch which dispatchs an event ... and you want the event handler to use the js/Notification API.

martinklepsch21:09:18

The basic thing I’m doing is this: 1. watch filesystem for some changes, pipe them into the system using dispatch 2. under some specific conditions call (js/Notification. “Test”) to trigger desktop notifications

mikethompson21:09:27

How long does it take for the fs.watch callback to run, I wonder. To kick start the process.

martinklepsch21:09:10

@mikethompson: I added the js/Notifcation. call directly to the callback that later calls dispatch and the notification fires immediately

mikethompson21:09:12

You've got multiple steps there ... and in a throttled tab each of them could take seconds

mikethompson21:09:38

If you use dispatch-sync (from your fs.watch callback) then you should likewise see something instant

mikethompson21:09:18

(Assuming the event handler servicing the dispatch-sync does the js/Notification call)

martinklepsch21:09:53

Right, that works. Then I only have to decouple that notification logic from the rest that can happen once the app has been activated again.

mikethompson21:09:30

@martinklepsch: no problems. Glad it works