planck

Planck ClojureScript REPL
johanatan 2016-06-09T02:31:16.000109Z

@mfikes: another interesting discovery

johanatan 2016-06-09T02:32:00.000110Z

I'm finding that when I issue an 'sh' with a long-running CPU-bound command (5-10 seconds on average), planck itself also uses 100% CPU. That doesn't seem right to me

johanatan 2016-06-09T02:32:04.000111Z

Any idea why that would happen?

johanatan 2016-06-09T02:32:36.000112Z

[I have 8 cores and end up using 200/800% during each of these-- 100% for each of planck and the command executed]

mfikes 2016-06-09T02:44:16.000113Z

@johanatan: Does the command itself emit a lot to stdout?

johanatan 2016-06-09T02:44:32.000115Z

@mfikes: nope, it's emitting nothing

mfikes 2016-06-09T02:45:18.000116Z

I agree. That does appear to be odd. There are a few bugs surrounding sh, this one being the most troubling: https://github.com/mfikes/planck/issues/88

johanatan 2016-06-09T02:46:24.000119Z

did you try reproducing?

mfikes 2016-06-09T02:46:24.000120Z

Feel free to log an issue… I plan to continue to work on sh until it is bug free

mfikes 2016-06-09T02:46:37.000121Z

Can’t yet (busy)

johanatan 2016-06-09T02:46:46.000122Z

ahh, ok. i will file an issue. thx!

mfikes 2016-06-09T02:46:50.000123Z

Thanks!

johanatan 2016-06-09T19:15:12.000124Z

@mfikes: I filed the issue and am now thinking that I'd like to take a stab at solving it. Do you have any tips/advice for how to approach this one?

mfikes 2016-06-09T19:16:48.000125Z

@johanatan: Here is where external shell tasks are executed: https://github.com/mfikes/planck/blob/master/planck/PLKSh.m#L117

mfikes 2016-06-09T19:17:28.000128Z

@johanatan: There is a Wiki page here describing stuff surrounding building Planck: https://github.com/mfikes/planck/wiki/Development

johanatan 2016-06-09T19:18:08.000131Z

ahh, this is the problem

johanatan 2016-06-09T19:18:19.000134Z

"polls the current run loop until the class exits"

mfikes 2016-06-09T19:18:20.000135Z

Other than that, it is using a fairly standard-looking way to launch processes

mfikes 2016-06-09T19:19:07.000136Z

If there is a better way, perhaps some other mechanism could be used, one that also doesn’t hang like NSTask appears to do

johanatan 2016-06-09T19:20:34.000137Z

I think it would be better to return immediately and allow the terminationHandler to 'wake' us back up: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTask_Class/#//apple_ref/occ/instp/NSTask/terminationHandler

mfikes 2016-06-09T19:21:42.000139Z

Give it a shot 🙂 There are definitely issues with the way it is currently being done.

johanatan 2016-06-09T19:21:57.000140Z

Ok. 🙂

johanatan 2016-06-09T19:31:14.000143Z

How is that even valid Objective-C?

johanatan 2016-06-09T19:31:19.000144Z

[Also throughout the file]

johanatan 2016-06-09T19:31:46.000145Z

Oh, nevermind.

johanatan 2016-06-09T19:31:58.000146Z

I see the close square bracket corresponds to line 172

mfikes 2016-06-09T19:32:09.000148Z

🙂 Obviously I don’t give much concern about the gracefulness of that code

johanatan 2016-06-09T19:32:20.000149Z

Haha, yea

mfikes 2016-06-09T19:32:34.000150Z

It is all just a means to make ClojureScript available 🙂

johanatan 2016-06-09T19:33:51.000151Z

Do you have any example in the code where an async method call from JS -> Obj-C -> JS is performed?

johanatan 2016-06-09T19:34:01.000152Z

[i.e., an Obj-C func that accepts a JS callback]

johanatan 2016-06-09T19:34:10.000153Z

That's probably what we'd have to do here I think.

mfikes 2016-06-09T19:34:42.000154Z

I think perhaps the timer callbacks are the only place

mfikes 2016-06-09T19:36:01.000155Z

If planck.shell/sh gains async, we’d have to figure out a way to support the older sync interface, and also, play the same trick to keep Planck processing alive when there are outstanding async tasks

johanatan 2016-06-09T19:36:43.000156Z

Actually I just thought of a simpler solution

johanatan 2016-06-09T19:36:49.000157Z

[for sync only]

johanatan 2016-06-09T19:37:23.000158Z

So, just replace the call to 'waitUntilExit' (which stupidly polls killing the CPU) with use of dispatch_semaphore .

johanatan 2016-06-09T19:37:35.000159Z

We'd still be 'blocking' but we wouldn't eat the CPU up while doing so. 🙂

mfikes 2016-06-09T19:37:56.000160Z

Worth a try

johanatan 2016-06-09T19:38:27.000161Z

[but yes going forward when the time is right for async, i think we'd want to follow the pattern of the timers on the js -> objc bridge side of things and use core.async/andare on the JS side]

johanatan 2016-06-09T19:38:52.000162Z

Ok, I'll give it a shot. Pretty sure it will work.

mfikes 2016-06-09T19:41:19.000163Z

Maybe there’s a slight chance something like that will fix #254

mfikes 2016-06-09T19:42:20.000164Z

The real problem (apart from hogging some CPU) is the inexplicable hanging that occurs if you try to use Planck to, say, run something that does a maven build or lein build, which makes it hard to use Planck to automate dev stuff

mfikes 2016-06-09T19:42:27.000165Z

(That’s #88)

johanatan 2016-06-09T19:58:38.000166Z

Bummer.

johanatan 2016-06-09T19:58:47.000167Z

These changes didn't help the CPU usage:

Jonathans-MacBook-Pro:planck jonathan$ git diff
diff --git a/planck/PLKSh.m b/planck/PLKSh.m
index 4e4b8b1..9387b26 100644
--- a/planck/PLKSh.m
+++ b/planck/PLKSh.m
@@ -111,11 +111,17 @@ NSDictionary* cljs_shell(NSArray *args, id arg_in, NSString *encoding_in, NSStri
         [errData appendData:data];
         [errLock unlock];
     }];
-    
+
+    NSLog(@"doing semaphore thingie\n");
+    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+    aTask.terminationHandler = ^(NSTask *task) {
+      dispatch_semaphore_signal(sema); };
+
     // We'll block during execution
     @try {
         [aTask launch];
-        [aTask waitUntilExit];
+        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
+        NSLog(@"done doing semaphore thingie\n");
     }
     @catch (NSException *exception) {
         return @{@"exit": @(-1),

johanatan 2016-06-09T20:00:43.000168Z

Looks like internally that method dispatch_sempahore_wait also polls 😮

johanatan 2016-06-09T20:01:37.000169Z

[According to 'Barry' on this page: http://stackoverflow.com/questions/4326350/how-do-i-wait-for-an-asynchronously-dispatched-block-to-finish , quote: "Yep, this is ghetto polling that will murder the battery" lol