emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATCH] expose nrepl's timeout setting in ob-clojure.el
@ 2016-03-29 17:38 Frederick Giasson
  2016-04-06  9:43 ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-03-29 17:38 UTC (permalink / raw)
  To: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 1082 bytes --]

Hi everybody,

I am starting to use org-mode to create literate applications in 
Clojure. So far so good, this is a terrific piece of software.

One thing why I wanted to use org-mode is to use it to create Clojure 
Notebooks. The problem I had is that I have many functions that can take 
some time (more than 10 seconds) to complete. This means that I was 
often receiving that error from nrepl:

===========
nrepl-send-sync-request: Sync nREPL request timed out (op eval session 
57bdacff-b178-4952-8bf8-5e01ac9d745a code (def umbel 
(create-ontology-structure))
===========

The problem is that there is no way to define the nrepl timeout from 
Org-mode. What I did is to expose that nrepl setting in ob-clojure.el. 
This is the ob-clojure.el.diff patch I am proposing here.

The name of the new setting is "org-babel-clojure-nrepl-timeout". If it 
is set to /nil/ then no timeout will occur, otherwise any integer will 
define a timeout value.

This variable can be set from the /.emacs/ global setting file.

It works fine from here, please modify as required.

Thanks,

Fred

[-- Attachment #1.2: Type: text/html, Size: 1527 bytes --]

[-- Attachment #2: ob-clojure.el.diff --]
[-- Type: text/plain, Size: 1634 bytes --]

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 89a09a9..46031e1 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -1,4 +1,4 @@
-;;; ob-clojure.el --- Babel Functions for Clojure    -*- lexical-binding: t; -*-
+;;; ob-clojure.el --- org-babel functions for clojure evaluation
 
 ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
 
@@ -55,6 +55,7 @@
 
 (defvar org-babel-default-header-args:clojure '())
 (defvar org-babel-header-args:clojure '((package . :any)))
+(defvar org-babel-clojure-nrepl-timeout 10)
 
 (defcustom org-babel-clojure-backend
   (cond ((featurep 'cider) 'cider)
@@ -67,7 +68,7 @@
 
 (defun org-babel-expand-body:clojure (body params)
   "Expand BODY according to PARAMS, return the expanded body."
-  (let* ((vars (org-babel--get-vars params))
+  (let* ((vars (mapcar #'cdr (org-babel-get-header params :var)))
 	 (result-params (cdr (assoc :result-params params)))
 	 (print-level nil) (print-length nil)
 	 (body (org-babel-trim
@@ -94,8 +95,9 @@
        (let ((result-params (cdr (assoc :result-params params))))
 	 (setq result
 	       (nrepl-dict-get
-		(nrepl-sync-request:eval
-		 expanded (cider-current-connection) (cider-current-session))
+		(let ((nrepl-sync-request-timeout org-babel-clojure-nrepl-timeout))
+		  (nrepl-sync-request:eval
+		   expanded (cider-current-connection) (cider-current-session)))
 		(if (or (member "output" result-params)
 			(member "pp" result-params))
 		    "out"

warning: LF will be replaced by CRLF in lisp/ob-clojure.el.
The file will have its original line endings in your working directory.

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-03-29 17:38 [PATCH] expose nrepl's timeout setting in ob-clojure.el Frederick Giasson
@ 2016-04-06  9:43 ` Nicolas Goaziou
  2016-04-06 14:48   ` Frederick Giasson
  2016-04-06 16:27   ` [PATCH] new :async feature for org-babel-clojure Frederick Giasson
  0 siblings, 2 replies; 13+ messages in thread
From: Nicolas Goaziou @ 2016-04-06  9:43 UTC (permalink / raw)
  To: Frederick Giasson; +Cc: emacs-orgmode

Hello,

Thank you for the patch.

Frederick Giasson <fred@fgiasson.com> writes:

> -;;; ob-clojure.el --- Babel Functions for Clojure    -*- lexical-binding: t; -*-
> +;;; ob-clojure.el --- org-babel functions for clojure evaluation

Your patch reverts a change introduced in development version. Could you
rebase it on top of latest Org first?

>  
>  ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
>  
> @@ -55,6 +55,7 @@
>  
>  (defvar org-babel-default-header-args:clojure '())
>  (defvar org-babel-header-args:clojure '((package . :any)))
> +(defvar org-babel-clojure-nrepl-timeout 10)

Would it make sense to turn it into a defcustom instead? If so, this
should be added in etc/ORG-NEWS file. Bonus points if Worg documentation
about this back-end 
>  
>  (defcustom org-babel-clojure-backend
>    (cond ((featurep 'cider) 'cider)
> @@ -67,7 +68,7 @@
>  
>  (defun org-babel-expand-body:clojure (body params)
>    "Expand BODY according to PARAMS, return the expanded body."
> -  (let* ((vars (org-babel--get-vars params))
> +  (let* ((vars (mapcar #'cdr (org-babel-get-header params :var)))

You are also reverting a previous change here.

>  	 (result-params (cdr (assoc :result-params params)))
>  	 (print-level nil) (print-length nil)
>  	 (body (org-babel-trim
> @@ -94,8 +95,9 @@
>         (let ((result-params (cdr (assoc :result-params params))))
>  	 (setq result
>  	       (nrepl-dict-get
> -		(nrepl-sync-request:eval
> -		 expanded (cider-current-connection) (cider-current-session))
> +		(let ((nrepl-sync-request-timeout org-babel-clojure-nrepl-timeout))
> +		  (nrepl-sync-request:eval
> +		   expanded (cider-current-connection) (cider-current-session)))

It seems you need to define `nrepl-sync-request-timeout' as
a dynamically scoped variable:

  (defvar nrepl-sync-request-timeout)

Indeed "ob-clojure.el" uses lexical binding, even though you disabled it
in the first line of your patch ;)

Eventually, could you add an appropriate commit message for this patch?
Something like

  ob-clojure: Make REPL timeout configurable

  * lisp/ob-clojure.el (org-babel-clojure-nrepl-timeout):  New variable.
  (org-babel-expand-body:clojure): Use new variable.

  ... explanations about the motivation of the change...


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-04-06  9:43 ` Nicolas Goaziou
@ 2016-04-06 14:48   ` Frederick Giasson
  2016-04-10  8:20     ` Nicolas Goaziou
  2016-04-06 16:27   ` [PATCH] new :async feature for org-babel-clojure Frederick Giasson
  1 sibling, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-04-06 14:48 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]

Hi Nicolas!

>> -;;; ob-clojure.el --- Babel Functions for Clojure    -*- lexical-binding: t; -*-
>> +;;; ob-clojure.el --- org-babel functions for clojure evaluation
> Your patch reverts a change introduced in development version. Could you
> rebase it on top of latest Org first?

Yeah sorry, I did this from the latest published version, not master. 
Fixed now.

>
>>   ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
>>   
>> @@ -55,6 +55,7 @@
>>   
>>   (defvar org-babel-default-header-args:clojure '())
>>   (defvar org-babel-header-args:clojure '((package . :any)))
>> +(defvar org-babel-clojure-nrepl-timeout 10)
> Would it make sense to turn it into a defcustom instead? If so, this
> should be added in etc/ORG-NEWS file.

Patch attached.

> Bonus points if Worg documentation
> about this back-end

Patch attached.

>
>>   (defcustom org-babel-clojure-backend
>>     (cond ((featurep 'cider) 'cider)
>> @@ -67,7 +68,7 @@
>>   
>>   (defun org-babel-expand-body:clojure (body params)
>>     "Expand BODY according to PARAMS, return the expanded body."
>> -  (let* ((vars (org-babel--get-vars params))
>> +  (let* ((vars (mapcar #'cdr (org-babel-get-header params :var)))
> You are also reverting a previous change here.

Fixed.

>
>> 	 (result-params (cdr (assoc :result-params params)))
>>   	 (print-level nil) (print-length nil)
>>   	 (body (org-babel-trim
>> @@ -94,8 +95,9 @@
>>          (let ((result-params (cdr (assoc :result-params params))))
>>   	 (setq result
>>   	       (nrepl-dict-get
>> -		(nrepl-sync-request:eval
>> -		 expanded (cider-current-connection) (cider-current-session))
>> +		(let ((nrepl-sync-request-timeout org-babel-clojure-nrepl-timeout))
>> +		  (nrepl-sync-request:eval
>> +		   expanded (cider-current-connection) (cider-current-session)))
> It seems you need to define `nrepl-sync-request-timeout' as
> a dynamically scoped variable:
>
>    (defvar nrepl-sync-request-timeout)
>
> Indeed "ob-clojure.el" uses lexical binding, even though you disabled it
> in the first line of your patch ;)

Fixed :)

> Eventually, could you add an appropriate commit message for this patch?
> Something like
>
>    ob-clojure: Make REPL timeout configurable
>
>    * lisp/ob-clojure.el (org-babel-clojure-nrepl-timeout):  New variable.
>    (org-babel-expand-body:clojure): Use new variable.
>
>    ... explanations about the motivation of the change...

Patch attached.


Hope everything is good now!

Thanks,

Fred


[-- Attachment #2: 0001-Document-the-new-option-ob-clojure-option-org-babel-.patch --]
[-- Type: text/plain, Size: 1216 bytes --]

From c8e89d774590e9b39604252b3a344f95b56e3924 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:00:18 -0400
Subject: [PATCH] Document the new option ob-clojure option
 "org-babel-clojure-sync-nrepl-timeout".

---
 org-contrib/babel/languages/ob-doc-clojure.org | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/org-contrib/babel/languages/ob-doc-clojure.org b/org-contrib/babel/languages/ob-doc-clojure.org
index 72942df..17c0f20 100644
--- a/org-contrib/babel/languages/ob-doc-clojure.org
+++ b/org-contrib/babel/languages/ob-doc-clojure.org
@@ -90,6 +90,17 @@ Add these lines to your .emacs file to configure CIDER:
   (require 'cider)
 #+END_SRC
 
+Optionally you can specify the Cider timeout by setting the =org-babel-clojure-sync-nrepl-timeout=
+setting option. The value is in seconds and if set to =nil= then no timeout will occur.
+
+#+BEGIN_SRC emacs-lisp
+  ; Disable Cider's timeout
+  (setq org-babel-clojure-sync-nrepl-timeout nil)
+
+  ; Set the timeout to 20 seconds
+  (setq org-babel-clojure-sync-nrepl-timeout 20)
+#+END_SRC
+
 ** Create a Clojure Project with Leiningen
 
 Create a Leiningen project directory tree:
-- 
1.9.5.msysgit.0


[-- Attachment #3: 0001-Update-of-ORG-NEWS-to-mention-the-addition-of-the-ne.patch --]
[-- Type: text/plain, Size: 918 bytes --]

From 9a81363719f3078d13de9b971440ee6fd456b4b2 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:24:54 -0400
Subject: [PATCH 1/2] Update of ORG-NEWS to mention the addition of the new
 setting "org-babel-clojure-sync-nrepl-timeout"

---
 etc/ORG-NEWS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 82d5ad0..e684587 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -106,6 +106,10 @@ becomes
 : ("pdf" . (lambda (file link) (foo)))
 
 ** New features
+*** New option =org-babel-clojure-sync-nrepl-timeout= for =org-babel-clojure=
+This new option tells the =org-babel-clojure= module the length of the timeout 
+of a synchronous call to the nREPL. This value is in seconds. If =nil= then
+no timeout will occur.
 *** New org-protocol key=value syntax
 
 Org-protocol can now handle query-style parameters such as:
-- 
1.9.5.msysgit.0


[-- Attachment #4: 0002-Addition-of-a-new-customization-variable-called-org-.patch --]
[-- Type: text/plain, Size: 1796 bytes --]

From dab6472228d1a0a41831dcae969335d0a7fb7531 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:46:35 -0400
Subject: [PATCH 2/2] Addition of a new customization variable called
 "org-babel-clojure-sync-nrepl-timeout" which expose the Cider timeout setting
 as a custom variable.

The timeout is in second, and if nil is specified and timeout is disabled.

With previous version, the timeout was set to 10 seconds, and if you were running a function that was taking more than 10 seconds, then you were getting a nREPL timeout error. This is why it is important to expose that setting to the org-mode users.
---
 lisp/ob-clojure.el | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 89a09a9..86f1cff 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -56,6 +56,12 @@
 (defvar org-babel-default-header-args:clojure '())
 (defvar org-babel-header-args:clojure '((package . :any)))
 
+(defcustom org-babel-clojure-sync-nrepl-timeout 10
+  "Timeout value, in seconds, of a Clojure sync call. 
+   If the value is nil, timeout is disabled."
+  :type 'integer
+  :group 'org-babel)
+
 (defcustom org-babel-clojure-backend
   (cond ((featurep 'cider) 'cider)
 	(t 'slime))
@@ -94,8 +100,9 @@
        (let ((result-params (cdr (assoc :result-params params))))
 	 (setq result
 	       (nrepl-dict-get
-		(nrepl-sync-request:eval
-		 expanded (cider-current-connection) (cider-current-session))
+		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
+		  (nrepl-sync-request:eval
+		   expanded (cider-current-connection) (cider-current-session)))
 		(if (or (member "output" result-params)
 			(member "pp" result-params))
 		    "out"
-- 
1.9.5.msysgit.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH] new :async feature for org-babel-clojure
  2016-04-06  9:43 ` Nicolas Goaziou
  2016-04-06 14:48   ` Frederick Giasson
@ 2016-04-06 16:27   ` Frederick Giasson
  2016-04-20 12:17     ` Frederick Giasson
  1 sibling, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-04-06 16:27 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 526 bytes --]

Hi,

Here is my proposal to create a new :async feature for 
Org-babel-clojure. This is discussed at length in this blog post:

http://fgiasson.com/blog/index.php/2016/04/05/using-clojure-in-org-mode-and-implementing-asynchronous-processing/

I added the commit of the changes, the commit for the ORG-NEWS file and 
the commit for the Worg documentation.

IMPORTANT NOTE: this includes the patches for the new :async feature 
*AND* the new org-babel-clojure-sync-nrepl-timeout setting (for 
consistency's sake)

Thanks,

Fred

[-- Attachment #2: 0003-Adding-information-about-the-new-org-babel-clojure-a.patch --]
[-- Type: text/plain, Size: 1340 bytes --]

From 2fe515d1fb89ba1ea160711d10f2f68fe0287246 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 12:18:21 -0400
Subject: [PATCH 3/4] Adding information about the new org-babel-clojure :async
 feature.

---
 etc/ORG-NEWS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index e684587..fad0679 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -110,6 +110,15 @@ becomes
 This new option tells the =org-babel-clojure= module the length of the timeout 
 of a synchronous call to the nREPL. This value is in seconds. If =nil= then
 no timeout will occur.
+*** New code block option =:async= for =org-babel-clojure=
+This new option gives the possibility to =org-babel-clojure= user to run
+a block code asynchronously using a new code block parameter =:async=.
+If =:async= is specified in the code block, then it will be processed
+asynchronously by Org-mode. This means that everything that will be 
+output to the REPL by the code will appear in a new window when it will
+be output. Once the processing is finalized, then the window will be closed
+and the output will be added to the results section (if =:results output= is 
+specified).
 *** New org-protocol key=value syntax
 
 Org-protocol can now handle query-style parameters such as:
-- 
1.9.5.msysgit.0


[-- Attachment #3: 0004-Adding-a-new-feature-async-feature-to-org-babel-cloj.patch --]
[-- Type: text/plain, Size: 4587 bytes --]

From e218aaef38f6dc0f9affa516aafa18b77c2a3a1e Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 12:19:11 -0400
Subject: [PATCH 4/4] Adding a new feature :async feature to org-babel-clojure.
 With this new feature, someone can evaluate Clojure code in Org-mode code
 blocks asynchronously.

---
 lisp/ob-clojure.el | 78 ++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 61 insertions(+), 17 deletions(-)

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 86f1cff..6059d7d 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -91,35 +91,79 @@
       body)))
 
 (defun org-babel-execute:clojure (body params)
-  "Execute a block of Clojure code with Babel."
+  "Execute a block of Clojure code with Babel. The block can be executed
+   synchenously by default or asynchronously with the :async parameter"
   (let ((expanded (org-babel-expand-body:clojure body params))
+	(sbuffer "*Clojure Sub Buffer*")
+	(async (if (assoc :async params) t nil))
+	(response (cons 'dict nil))
+	status
 	result)
     (case org-babel-clojure-backend
       (cider
        (require 'cider)
        (let ((result-params (cdr (assoc :result-params params))))
-	 (setq result
-	       (nrepl-dict-get
-		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
-		  (nrepl-sync-request:eval
-		   expanded (cider-current-connection) (cider-current-session)))
-		(if (or (member "output" result-params)
-			(member "pp" result-params))
-		    "out"
-		  "value")))))
+         ; Check if the user want to run code asynchronously
+         (when async
+           ; Create a new window with the async output buffer
+           (switch-to-buffer-other-window sbuffer)
+
+           ; Run the Clojure code asynchronously in nREPL
+           (nrepl-request:eval
+            expanded 
+            (lambda (resp) 
+              (when (member "out" resp)
+                ; Print the output of the nREPL in the asyn output buffer
+                (princ (nrepl-dict-get resp "out") (get-buffer sbuffer)))
+              (nrepl--merge response resp)
+              ; Update the status of the nREPL output session
+              (setq status (nrepl-dict-get response "status")))
+            (cider-current-connection) 
+            (cider-current-session))
+           
+           ; Wait until the nREPL code finished to be processed
+           (while (not (member "done" status))
+             (nrepl-dict-put response "status" (remove "need-input" status))
+             (accept-process-output nil 0.01)
+             (redisplay))
+
+           ; Delete the async buffer & window when the processing is finalized
+           (let ((wins (get-buffer-window-list sbuffer nil t)))
+             (dolist (win wins)
+               (delete-window win))
+             (kill-buffer sbuffer))
+             
+           ; Put the output or the value in the result section of the code block
+           (setq result (nrepl-dict-get response 
+                                        (if (or (member "output" result-params)
+                                                (member "pp" result-params))
+                                            "out"
+                                          "value"))))
+         ; Check if user want to run code synchronously
+         (when (not async)
+           (setq result
+                 (nrepl-dict-get
+                  (let ((nrepl-sync-request-timeout 
+                         org-babel-clojure-sync-nrepl-timeout))
+                    (nrepl-sync-request:eval
+                     expanded (cider-current-connection) (cider-current-session)))
+                  (if (or (member "output" result-params)
+                          (member "pp" result-params))
+                      "out"
+                    "value"))))))
       (slime
        (require 'slime)
        (with-temp-buffer
-	 (insert expanded)
-	 (setq result
-	       (slime-eval
-		`(swank:eval-and-grab-output
-		  ,(buffer-substring-no-properties (point-min) (point-max)))
-		(cdr (assoc :package params)))))))
+         (insert expanded)
+         (setq result
+               (slime-eval
+                `(swank:eval-and-grab-output
+                  ,(buffer-substring-no-properties (point-min) (point-max)))
+                (cdr (assoc :package params)))))))
     (org-babel-result-cond (cdr (assoc :result-params params))
       result
       (condition-case nil (org-babel-script-escape result)
-	(error result)))))
+        (error result)))))
 
 (provide 'ob-clojure)
 
-- 
1.9.5.msysgit.0


[-- Attachment #4: 0001-Update-of-ORG-NEWS-to-mention-the-addition-of-the-ne.patch --]
[-- Type: text/plain, Size: 918 bytes --]

From 9a81363719f3078d13de9b971440ee6fd456b4b2 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:24:54 -0400
Subject: [PATCH 1/4] Update of ORG-NEWS to mention the addition of the new
 setting "org-babel-clojure-sync-nrepl-timeout"

---
 etc/ORG-NEWS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 82d5ad0..e684587 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -106,6 +106,10 @@ becomes
 : ("pdf" . (lambda (file link) (foo)))
 
 ** New features
+*** New option =org-babel-clojure-sync-nrepl-timeout= for =org-babel-clojure=
+This new option tells the =org-babel-clojure= module the length of the timeout 
+of a synchronous call to the nREPL. This value is in seconds. If =nil= then
+no timeout will occur.
 *** New org-protocol key=value syntax
 
 Org-protocol can now handle query-style parameters such as:
-- 
1.9.5.msysgit.0


[-- Attachment #5: 0002-Addition-of-a-new-customization-variable-called-org-.patch --]
[-- Type: text/plain, Size: 1796 bytes --]

From dab6472228d1a0a41831dcae969335d0a7fb7531 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:46:35 -0400
Subject: [PATCH 2/4] Addition of a new customization variable called
 "org-babel-clojure-sync-nrepl-timeout" which expose the Cider timeout setting
 as a custom variable.

The timeout is in second, and if nil is specified and timeout is disabled.

With previous version, the timeout was set to 10 seconds, and if you were running a function that was taking more than 10 seconds, then you were getting a nREPL timeout error. This is why it is important to expose that setting to the org-mode users.
---
 lisp/ob-clojure.el | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el
index 89a09a9..86f1cff 100644
--- a/lisp/ob-clojure.el
+++ b/lisp/ob-clojure.el
@@ -56,6 +56,12 @@
 (defvar org-babel-default-header-args:clojure '())
 (defvar org-babel-header-args:clojure '((package . :any)))
 
+(defcustom org-babel-clojure-sync-nrepl-timeout 10
+  "Timeout value, in seconds, of a Clojure sync call. 
+   If the value is nil, timeout is disabled."
+  :type 'integer
+  :group 'org-babel)
+
 (defcustom org-babel-clojure-backend
   (cond ((featurep 'cider) 'cider)
 	(t 'slime))
@@ -94,8 +100,9 @@
        (let ((result-params (cdr (assoc :result-params params))))
 	 (setq result
 	       (nrepl-dict-get
-		(nrepl-sync-request:eval
-		 expanded (cider-current-connection) (cider-current-session))
+		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
+		  (nrepl-sync-request:eval
+		   expanded (cider-current-connection) (cider-current-session)))
 		(if (or (member "output" result-params)
 			(member "pp" result-params))
 		    "out"
-- 
1.9.5.msysgit.0


[-- Attachment #6: 0001-Document-the-new-option-ob-clojure-option-org-babel-.patch --]
[-- Type: text/plain, Size: 1220 bytes --]

From c8e89d774590e9b39604252b3a344f95b56e3924 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 10:00:18 -0400
Subject: [PATCH 1/2] Document the new option ob-clojure option
 "org-babel-clojure-sync-nrepl-timeout".

---
 org-contrib/babel/languages/ob-doc-clojure.org | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/org-contrib/babel/languages/ob-doc-clojure.org b/org-contrib/babel/languages/ob-doc-clojure.org
index 72942df..17c0f20 100644
--- a/org-contrib/babel/languages/ob-doc-clojure.org
+++ b/org-contrib/babel/languages/ob-doc-clojure.org
@@ -90,6 +90,17 @@ Add these lines to your .emacs file to configure CIDER:
   (require 'cider)
 #+END_SRC
 
+Optionally you can specify the Cider timeout by setting the =org-babel-clojure-sync-nrepl-timeout=
+setting option. The value is in seconds and if set to =nil= then no timeout will occur.
+
+#+BEGIN_SRC emacs-lisp
+  ; Disable Cider's timeout
+  (setq org-babel-clojure-sync-nrepl-timeout nil)
+
+  ; Set the timeout to 20 seconds
+  (setq org-babel-clojure-sync-nrepl-timeout 20)
+#+END_SRC
+
 ** Create a Clojure Project with Leiningen
 
 Create a Leiningen project directory tree:
-- 
1.9.5.msysgit.0


[-- Attachment #7: 0002-Documentation-for-the-new-org-babel-clojure-async-fe.patch --]
[-- Type: text/plain, Size: 1985 bytes --]

From cbe52d3e91d02041513fe3ff149b766b48ad09d8 Mon Sep 17 00:00:00 2001
From: Frederick Giasson <fred@fgiasson.com>
Date: Wed, 6 Apr 2016 12:13:21 -0400
Subject: [PATCH 2/2] Documentation for the new org-babel-clojure :async
 feature.

---
 org-contrib/babel/languages/ob-doc-clojure.org | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/org-contrib/babel/languages/ob-doc-clojure.org b/org-contrib/babel/languages/ob-doc-clojure.org
index 17c0f20..d309975 100644
--- a/org-contrib/babel/languages/ob-doc-clojure.org
+++ b/org-contrib/babel/languages/ob-doc-clojure.org
@@ -145,6 +145,31 @@ Another source for information on options is this page at Worg:
  
 Next, a similar process for executing code will be used with Clojure.
 
+* Using Asynchronous Evaluations
+Org-babel-clojure does support asynchronous evaluation of the code blocks. To
+evaluate some code asynchronously, you only have to specify the =:async= option
+in the code block's header like this:
+
+#+begin_example
+#+BEGIN_SRC clojure :results output :async
+  (dotimes [n 10]
+    (println n ".")
+    (Thread/sleep 500))
+#+END_SRC
+#+end_example
+
+If =:async= is specified that way, then when you will run the code using
+=C-c C-c= then a new window will open in Emacs. Everything that is output
+by the REPL will immediately be added to that new window.
+
+When the processing of the code is finished, then the window and its
+buffer will be closed and the results will be reported in the
+=#+RESULTS= section. Note that the =:results= parameter like normally. If
+=silent= is specified, then no result will be displayed. If =output= is
+specified then all the output from the window will appears in the results
+section. If =value= is specified, then only the last returned value of
+the code will be displayed in the results section.
+
 * Connect to the REPL
 
 To compile and run Clojure code, you will need to connect to a REPL (Read Evaluation Print Loop).
-- 
1.9.5.msysgit.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-04-06 14:48   ` Frederick Giasson
@ 2016-04-10  8:20     ` Nicolas Goaziou
  2016-04-11 14:03       ` Frederick Giasson
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2016-04-10  8:20 UTC (permalink / raw)
  To: Frederick Giasson; +Cc: emacs-orgmode

Hello,

Thank you for the update.

Frederick Giasson <fred@fgiasson.com> writes:

> +(defcustom org-babel-clojure-sync-nrepl-timeout 10
> +  "Timeout value, in seconds, of a Clojure sync call. 
> +   If the value is nil, timeout is disabled."
> +  :type 'integer
> +  :group 'org-babel)

Some keywords are missing:

  :version "25.1"
  :package-version '(Org . "9.0")

and perhaps

  :safe #'wholenump

>  (defcustom org-babel-clojure-backend
>    (cond ((featurep 'cider) 'cider)
>  	(t 'slime))
> @@ -94,8 +100,9 @@
>         (let ((result-params (cdr (assoc :result-params params))))
>  	 (setq result
>  	       (nrepl-dict-get
> -		(nrepl-sync-request:eval
> -		 expanded (cider-current-connection) (cider-current-session))
> +		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
> +		  (nrepl-sync-request:eval
> +		   expanded (cider-current-connection) (cider-current-session)))

You forgot to

(defvar nrepl-sync-request-timeout)

I also think it makes sense to merge the 3 patches.

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-04-10  8:20     ` Nicolas Goaziou
@ 2016-04-11 14:03       ` Frederick Giasson
  2016-04-12 20:18         ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-04-11 14:03 UTC (permalink / raw)
  To: emacs-orgmode

Hi Nicolas,

> Some keywords are missing:
>
>    :version "25.1"
>    :package-version '(Org . "9.0")
>
> and perhaps
>
>    :safe #'wholenump

Ok good, added.


>>   (defcustom org-babel-clojure-backend
>>     (cond ((featurep 'cider) 'cider)
>>   	(t 'slime))
>> @@ -94,8 +100,9 @@
>>          (let ((result-params (cdr (assoc :result-params params))))
>>   	 (setq result
>>   	       (nrepl-dict-get
>> -		(nrepl-sync-request:eval
>> -		 expanded (cider-current-connection) (cider-current-session))
>> +		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
>> +		  (nrepl-sync-request:eval
>> +		   expanded (cider-current-connection) (cider-current-session)))
> You forgot to
>
> (defvar nrepl-sync-request-timeout)

This one is defined in the nREPL package. Maybe there is something that 
I don't understand, but do I have to re-defined it here?

> I also think it makes sense to merge the 3 patches.

Ok will do.

Thanks,

Fred

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-04-11 14:03       ` Frederick Giasson
@ 2016-04-12 20:18         ` Nicolas Goaziou
  2016-04-13 20:15           ` Frederick Giasson
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2016-04-12 20:18 UTC (permalink / raw)
  To: Frederick Giasson; +Cc: emacs-orgmode

Hello,

Frederick Giasson <fred@fgiasson.com> writes:

>>>   	 (setq result
>>>   	       (nrepl-dict-get
>>> -		(nrepl-sync-request:eval
>>> -		 expanded (cider-current-connection) (cider-current-session))
>>> +		(let ((nrepl-sync-request-timeout org-babel-clojure-sync-nrepl-timeout))
>>> +		  (nrepl-sync-request:eval
>>> +		   expanded (cider-current-connection) (cider-current-session)))
>> You forgot to
>>
>> (defvar nrepl-sync-request-timeout)
>
> This one is defined in the nREPL package. Maybe there is something
> that I don't understand, but do I have to re-defined it here?

The byte-compiler complains if a variable is let-bound but yet not used
in the body. You don't need to define it again but tell the
byte-compiler it is dynamically scoped (using `defvar' without a value).

Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] expose nrepl's timeout setting in ob-clojure.el
  2016-04-12 20:18         ` Nicolas Goaziou
@ 2016-04-13 20:15           ` Frederick Giasson
  0 siblings, 0 replies; 13+ messages in thread
From: Frederick Giasson @ 2016-04-13 20:15 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 147 bytes --]

Hi Nicolas,

> (defvar nrepl-sync-request-timeout)


Here are the latest fixes you proposed, everything should be all right now.


Thanks!


Fred


[-- Attachment #2: org-mode-patches.zip --]
[-- Type: application/x-zip-compressed, Size: 5217 bytes --]

[-- Attachment #3: worg-patches.zip --]
[-- Type: application/x-zip-compressed, Size: 2031 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] new :async feature for org-babel-clojure
  2016-04-06 16:27   ` [PATCH] new :async feature for org-babel-clojure Frederick Giasson
@ 2016-04-20 12:17     ` Frederick Giasson
  2016-04-20 21:59       ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-04-20 12:17 UTC (permalink / raw)
  To: emacs-orgmode

Hi Nicolas,

Any news regarding these latest fixes to that patch?

Thanks,

Fred

>
> Here is my proposal to create a new :async feature for 
> Org-babel-clojure. This is discussed at length in this blog post:
>
> http://fgiasson.com/blog/index.php/2016/04/05/using-clojure-in-org-mode-and-implementing-asynchronous-processing/ 
>
>
> I added the commit of the changes, the commit for the ORG-NEWS file 
> and the commit for the Worg documentation.
>
> IMPORTANT NOTE: this includes the patches for the new :async feature 
> *AND* the new org-babel-clojure-sync-nrepl-timeout setting (for 
> consistency's sake)
>
> Thanks,
>
> Fred

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] new :async feature for org-babel-clojure
  2016-04-20 12:17     ` Frederick Giasson
@ 2016-04-20 21:59       ` Nicolas Goaziou
  2016-04-21 12:34         ` Frederick Giasson
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2016-04-20 21:59 UTC (permalink / raw)
  To: Frederick Giasson; +Cc: emacs-orgmode

Hello,

Frederick Giasson <fred@fgiasson.com> writes:

> Any news regarding these latest fixes to that patch?

They look good. Thank you for the heads-up.

Could you merge patches 1 2 and 5 (Org series) into a single one for
inclusion?

As for 3 and 4, I think a more general mechanism for asynchrnous
eval'ing would be preferable. Besides, AFAIU, because of

   ; Wait until the nREPL code finished to be processed
   (while (not (member "done" status))
     (nrepl-dict-put response "status" (remove "need-input" status))
     (accept-process-output nil 0.01)
     (redisplay))

`org-babel-execute:clojure' is still somewhat synchronous, isn't it?


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] new :async feature for org-babel-clojure
  2016-04-20 21:59       ` Nicolas Goaziou
@ 2016-04-21 12:34         ` Frederick Giasson
  2016-04-26 19:21           ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Frederick Giasson @ 2016-04-21 12:34 UTC (permalink / raw)
  To: emacs-orgmode

Hi Nicolas,

> As for 3 and 4, I think a more general mechanism for asynchrnous
> eval'ing would be preferable. Besides, AFAIU, because of
>
>     ; Wait until the nREPL code finished to be processed
>     (while (not (member "done" status))
>       (nrepl-dict-put response "status" (remove "need-input" status))
>       (accept-process-output nil 0.01)
>       (redisplay))
>
> `org-babel-execute:clojure' is still somewhat synchronous, isn't it?


Yes, and this is what I was mentioning initially (here, I think, and on 
my blogpost about it). I just don't know how all this processing could 
be handled in a different thread. That way it would free the current 
threads and we could continue to work with the current instance while 
the processing is happening because as I mentioned, everything is still 
stuck during the processing.

Right now, async is really more about "feedback" than "asynchronous". 
However it has never been clear is it was possible or not, and if so, how :)

Any pointers on how this could be done in emacs?

Thanks,

Fred

>
>
> Regards,
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] new :async feature for org-babel-clojure
  2016-04-21 12:34         ` Frederick Giasson
@ 2016-04-26 19:21           ` Nicolas Goaziou
  2016-04-27 12:00             ` Frederick Giasson
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2016-04-26 19:21 UTC (permalink / raw)
  To: Frederick Giasson; +Cc: emacs-orgmode

Hello,

Frederick Giasson <fred@fgiasson.com> writes:

> Right now, async is really more about "feedback" than "asynchronous".
> However it has never been clear is it was possible or not, and if so,
> how :)
>
> Any pointers on how this could be done in emacs?

You could start a new Emacs evaluating some code in a subprocess, with
`start-process' and collect return value. You may want to have a look at
`org-export-async-start' or "async.el" library in ELPA.

Unfortunately, it is not yet possible to re-use the latter in Org code,
since it is unavailable in vanilla Emacs.

The hard part, IMO, is to bring the right context in the subprocess
(e.g., the environment should be the same, other blocks may be needed,
etc.).


Regards,

-- 
Nicolas Goaziou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] new :async feature for org-babel-clojure
  2016-04-26 19:21           ` Nicolas Goaziou
@ 2016-04-27 12:00             ` Frederick Giasson
  0 siblings, 0 replies; 13+ messages in thread
From: Frederick Giasson @ 2016-04-27 12:00 UTC (permalink / raw)
  To: emacs-orgmode

Hi Nicolas,

>
>> Right now, async is really more about "feedback" than "asynchronous".
>> However it has never been clear is it was possible or not, and if so,
>> how :)
>>
>> Any pointers on how this could be done in emacs?
> You could start a new Emacs evaluating some code in a subprocess, with
> `start-process' and collect return value. You may want to have a look at
> `org-export-async-start' or "async.el" library in ELPA.
>
> Unfortunately, it is not yet possible to re-use the latter in Org code,
> since it is unavailable in vanilla Emacs.
>
> The hard part, IMO, is to bring the right context in the subprocess
> (e.g., the environment should be the same, other blocks may be needed,
> etc.).

Yeah, will have to take some more time to check that, I probably have 
much to learn regarding Elisp itself first.

Rethinking about that, would it not be better to remove the confusion by 
changing the terminology I used: ":async"? What it really is is to have 
feedback of the underlying process, and not really an asynchronous process.

I thought about two possibilities:

   (1) creating two new results options: :output-process and 
:value-process. Which means that we output the underlying process of a 
:output or :value :results
   (2) renaming :async by :show-process or something similar.

Then we take the time to check how a real asynchronous system can be put 
in place.

Thoughts?

Thanks,

Fred


>
>
> Regards,
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-04-27 12:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-29 17:38 [PATCH] expose nrepl's timeout setting in ob-clojure.el Frederick Giasson
2016-04-06  9:43 ` Nicolas Goaziou
2016-04-06 14:48   ` Frederick Giasson
2016-04-10  8:20     ` Nicolas Goaziou
2016-04-11 14:03       ` Frederick Giasson
2016-04-12 20:18         ` Nicolas Goaziou
2016-04-13 20:15           ` Frederick Giasson
2016-04-06 16:27   ` [PATCH] new :async feature for org-babel-clojure Frederick Giasson
2016-04-20 12:17     ` Frederick Giasson
2016-04-20 21:59       ` Nicolas Goaziou
2016-04-21 12:34         ` Frederick Giasson
2016-04-26 19:21           ` Nicolas Goaziou
2016-04-27 12:00             ` Frederick Giasson

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).