From 1ad0b71d6c5f9632a1b9e170fabdcf399ab595e3 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 20 Jun 2012 20:56:04 +0200 Subject: [PATCH 01/11] Add ein:query-singleton-ajax --- ein-query.el | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ein-query.el b/ein-query.el index e0267ef..e02de64 100644 --- a/ein-query.el +++ b/ein-query.el @@ -212,6 +212,31 @@ is killed immediately after the execution of this function. (cancel-timer ein:query-ajax-timer) (setq ein:query-ajax-timer nil))) +(defvar ein:query-running-process-table (make-hash-table :test 'equal)) + +(defun ein:query-singleton-ajax (key &rest args) + "Cancel the old process if there is a process associated with +KEY, then call `ein:query-ajax' with ARGS. KEY is compared by +`equal'." + (ein:query-gc-running-process-table) + (ein:aif (gethash key ein:query-running-process-table) + (ein:with-live-buffer it + (setq ein:query-ajax-canceled 'user-cancel) + (let ((proc (get-buffer-process it))) + ;; This will call `ein:query-ajax-callback'. + (delete-process proc)))) + (let ((buffer (apply #'ein:query-ajax args))) + (puthash key buffer ein:query-running-process-table) + buffer)) + +(defun ein:query-gc-running-process-table () + "Garbage collect dead processes in `ein:query-running-process-table'." + (maphash + (lambda (key buffer) + (unless (buffer-live-p buffer) + (remhash key ein:query-running-process-table))) + ein:query-running-process-table)) + (provide 'ein-query) ;;; ein-query.el ends here From 99660cf5e7ba3507badf357a6123e15f9a4f35c3 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 20 Jun 2012 21:01:58 +0200 Subject: [PATCH 02/11] Use ein:query-singleton-ajax everywhere --- ein-kernel.el | 12 ++++++++---- ein-notebook.el | 8 ++++++-- ein-notebooklist.el | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ein-kernel.el b/ein-kernel.el index 0782bd0..30e8d6a 100644 --- a/ein-kernel.el +++ b/ein-kernel.el @@ -110,7 +110,8 @@ FIXME: document other slots." (defun ein:kernel-start (kernel notebook-id) "Start kernel of the notebook whose id is NOTEBOOK-ID." (unless (ein:$kernel-running kernel) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'kernel-start (ein:$kernel-kernel-id kernel)) (concat (ein:url (ein:$kernel-url-or-port kernel) (ein:$kernel-base-url kernel)) "?" (format "notebook=%s" notebook-id)) @@ -125,7 +126,8 @@ FIXME: document other slots." (ein:log 'info "Restarting kernel") (when (ein:$kernel-running kernel) (ein:kernel-stop-channels kernel) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'kernel-restart (ein:$kernel-kernel-id kernel)) (ein:url (ein:$kernel-url-or-port kernel) (ein:$kernel-kernel-url kernel) "restart") @@ -391,7 +393,8 @@ http://ipython.org/ipython-doc/dev/development/messaging.html#complete (defun ein:kernel-interrupt (kernel) (when (ein:$kernel-running kernel) (ein:log 'info "Interrupting kernel") - (ein:query-ajax + (ein:query-singleton-ajax + (list 'kernel-interrupt (ein:$kernel-kernel-id kernel)) (ein:url (ein:$kernel-url-or-port kernel) (ein:$kernel-kernel-url kernel) "interrupt") @@ -403,7 +406,8 @@ http://ipython.org/ipython-doc/dev/development/messaging.html#complete (defun ein:kernel-kill (kernel &optional callback cbargs) (when (ein:$kernel-running kernel) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'kernel-kill (ein:$kernel-kernel-id kernel)) (ein:url (ein:$kernel-url-or-port kernel) (ein:$kernel-kernel-url kernel)) :cache nil diff --git a/ein-notebook.el b/ein-notebook.el index 6b8831e..f3a558d 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -285,7 +285,8 @@ See `ein:notebook-open' for more information." (let ((url (ein:notebook-url-from-url-and-id url-or-port notebook-id)) (notebook (ein:notebook-new url-or-port notebook-id))) (ein:log 'debug "Opening notebook at %s" url) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'notebook-open url-or-port notebook-id) url :parser #'ein:json-read :success (cons #'ein:notebook-request-open-callback-with-callback @@ -994,7 +995,10 @@ shared output buffer. You can open the buffer by the command (push `(nbformat . ,(ein:$notebook-nbformat notebook)) data) (ein:events-trigger (ein:$notebook-events notebook) 'notebook_saving.Notebook) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'notebook-save + (ein:$notebook-url-or-port notebook) + (ein:$notebook-notebook-id notebook)) (ein:notebook-url notebook) :type "PUT" :headers '(("Content-Type" . "application/json")) diff --git a/ein-notebooklist.el b/ein-notebooklist.el index c2554e6..302c20b 100644 --- a/ein-notebooklist.el +++ b/ein-notebooklist.el @@ -91,7 +91,8 @@ (lambda (&rest args) (pop-to-buffer (apply #'ein:notebooklist-url-retrieve-callback args)))))) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'notebooklist-open url-or-port) (ein:notebooklist-url url-or-port) :cache nil :parser #'ein:json-read @@ -146,7 +147,8 @@ (assert url-or-port nil (concat "URL-OR-PORT is not given and the current buffer " "is not the notebook list buffer.")) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'notebooklist-new-notebook url-or-port) (ein:notebooklist-new-url url-or-port) :parser (lambda () (ein:notebooklist-get-data-in-body-tag "data-notebook-id")) @@ -200,7 +202,9 @@ This value is used from `ein:notebooklist-new-scratch-notebook'." (defun ein:notebooklist-delete-notebook (notebook-id name) (message "Deleting notebook %s..." name) - (ein:query-ajax + (ein:query-singleton-ajax + (list 'notebooklist-delete-notebook + (ein:$notebooklist-url-or-port ein:notebooklist) notebook-id) (ein:notebook-url-from-url-and-id (ein:$notebooklist-url-or-port ein:notebooklist) notebook-id) From 976bb3fefbbc173ad2fcb878934f8c48e5f6c78d Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Wed, 20 Jun 2012 21:13:28 +0200 Subject: [PATCH 03/11] Make notebook save callback more user cancel aware --- ein-notebook.el | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ein-notebook.el b/ein-notebook.el index f3a558d..dfe2ba3 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -1045,10 +1045,13 @@ shared output buffer. You can open the buffer by the command (ein:events-trigger (ein:$notebook-events notebook) 'notebook_saved.Notebook)) -(defun ein:notebook-save-notebook-error (notebook &rest ignore) - (ein:log 'info "Failed to save notebook!") - (ein:events-trigger (ein:$notebook-events notebook) - 'notebook_save_failed.Notebook)) +(defun* ein:notebook-save-notebook-error (notebook &key symbol-status + &allow-other-keys) + (if (eq symbol-status 'user-cancel) + (ein:log 'info "Cancel saving notebook.") + (ein:log 'info "Failed to save notebook!") + (ein:events-trigger (ein:$notebook-events notebook) + 'notebook_save_failed.Notebook))) (defun ein:notebook-rename-command (name) "Rename current notebook and save it immediately. From 283615ee50d68e4cc0f173fdbf4a37dbe4e8fc4c Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 00:01:23 +0200 Subject: [PATCH 04/11] Add ein:notebook-querty-timeout-open/save --- ein-notebook.el | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ein-notebook.el b/ein-notebook.el index dfe2ba3..495432a 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -115,6 +115,21 @@ yet. So be careful when using EIN functions. They may change." (yes t) (t (funcall ein:notebook-discard-output-on-save notebook cell)))) +;; As opening/saving notebook treats possibly huge data, define these +;; timeouts separately: + +(defcustom ein:notebook-querty-timeout-open (* 60 1000) ; 1 min + "Query timeout for opening notebook." + :type '(choice (integer :tag "Timeout [ms]" 5000) + (const :tag "No timeout" nil)) + :group 'ein) + +(defcustom ein:notebook-querty-timeout-save (* 10 1000) ; 10 sec + "Query timeout for saving notebook." + :type '(choice (integer :tag "Timeout [ms]" 5000) + (const :tag "No timeout" nil)) + :group 'ein) + ;;; Class and variable @@ -288,6 +303,7 @@ See `ein:notebook-open' for more information." (ein:query-singleton-ajax (list 'notebook-open url-or-port notebook-id) url + :timeout ein:notebook-querty-timeout-open :parser #'ein:json-read :success (cons #'ein:notebook-request-open-callback-with-callback (list notebook callback cbargs))) @@ -1000,6 +1016,7 @@ shared output buffer. You can open the buffer by the command (ein:$notebook-url-or-port notebook) (ein:$notebook-notebook-id notebook)) (ein:notebook-url notebook) + :timeout ein:notebook-querty-timeout-save :type "PUT" :headers '(("Content-Type" . "application/json")) :cache nil From 0bf69e5e7bf9497d78dfd6b4ed008123efa7b945 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 00:02:14 +0200 Subject: [PATCH 05/11] Make default query timeout shorter --- ein-query.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ein-query.el b/ein-query.el index e02de64..0bdcac0 100644 --- a/ein-query.el +++ b/ein-query.el @@ -46,7 +46,7 @@ ;;; Variables -(defcustom ein:query-timeout 5000 +(defcustom ein:query-timeout 1000 "Default query timeout for HTTP access in millisecond." :type '(choice (integer :tag "Timeout [ms]" 5000) (const :tag "No timeout" nil)) From 1b7edc7aa1c65a4d1a7ff6c8033e0e109fe9287d Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 00:38:15 +0200 Subject: [PATCH 06/11] Document query timeout configurations --- doc/source/index.rst | 2 ++ ein-notebook.el | 10 ++++++++-- ein-query.el | 17 ++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/doc/source/index.rst b/doc/source/index.rst index cc408b5..61831e4 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -254,6 +254,8 @@ Notebook list .. el:variable:: ein:url-or-port .. el:variable:: ein:default-url-or-port +.. el:variable:: ein:notebook-querty-timeout-open +.. el:variable:: ein:notebook-querty-timeout-save .. el:variable:: ein:scratch-notebook-name-template Notebook diff --git a/ein-notebook.el b/ein-notebook.el index 495432a..c36a099 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -119,13 +119,19 @@ yet. So be careful when using EIN functions. They may change." ;; timeouts separately: (defcustom ein:notebook-querty-timeout-open (* 60 1000) ; 1 min - "Query timeout for opening notebook." + "Query timeout for opening notebook. +If you cannot open large notebook because of timeout error, try +to increase this value. For global setting and more information, +see `ein:query-timeout'." :type '(choice (integer :tag "Timeout [ms]" 5000) (const :tag "No timeout" nil)) :group 'ein) (defcustom ein:notebook-querty-timeout-save (* 10 1000) ; 10 sec - "Query timeout for saving notebook." + "Query timeout for saving notebook. +Similar to `ein:notebook-querty-timeout-open', but for saving +notebook. For global setting and more information, see +`ein:query-timeout'." :type '(choice (integer :tag "Timeout [ms]" 5000) (const :tag "No timeout" nil)) :group 'ein) diff --git a/ein-query.el b/ein-query.el index 0bdcac0..8bc1abf 100644 --- a/ein-query.el +++ b/ein-query.el @@ -47,7 +47,22 @@ ;;; Variables (defcustom ein:query-timeout 1000 - "Default query timeout for HTTP access in millisecond." + "Default query timeout for HTTP access in millisecond. + +Setting this to `nil' means no timeout. + +If you do the same operation before the timeout, old operation +will be canceled \(see also `ein:query-singleton-ajax'). + +.. note:: This value exists because it looks like `url-retrieve' + occasionally fails to finish \(start?) querying. To let user + notice that their operation is not finished, timeout is + important. It also prevent opening a lot of useless process + buffers. If you know how to fix the problem with `url-retrieve', + please let me know or send pull request at github! + + \(Related bug report in Emacs bug tracker: + http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11469)" :type '(choice (integer :tag "Timeout [ms]" 5000) (const :tag "No timeout" nil)) :group 'ein) From c52c05836e72944f4c4d3ee60e22eb143472eb05 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 01:05:42 +0200 Subject: [PATCH 07/11] Increase ein:notebook-querty-timeout-save I checked that ein:notebook-querty-timeout-open/save are enough for opening/saving 50MB notebook in my machine. --- ein-notebook.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ein-notebook.el b/ein-notebook.el index c36a099..4c337ce 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -127,7 +127,7 @@ see `ein:query-timeout'." (const :tag "No timeout" nil)) :group 'ein) -(defcustom ein:notebook-querty-timeout-save (* 10 1000) ; 10 sec +(defcustom ein:notebook-querty-timeout-save (* 60 1000) ; 1 min "Query timeout for saving notebook. Similar to `ein:notebook-querty-timeout-open', but for saving notebook. For global setting and more information, see From 38a3533e8f234721d128ede1e522cbc01e8e6c9e Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 01:05:54 +0200 Subject: [PATCH 08/11] Minor fix in ein:query-ajax-timeout-callback --- ein-query.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ein-query.el b/ein-query.el index 8bc1abf..ca71efc 100644 --- a/ein-query.el +++ b/ein-query.el @@ -214,7 +214,7 @@ is killed immediately after the execution of this function. (defun* ein:query-ajax-timeout-callback (buffer &key (error nil) &allow-other-keys) - (ein:log 'debug "EIN:QUERY-AJAX-TIMEOUT-CALLBACK buffer = %s" buffer) + (ein:log 'debug "EIN:QUERY-AJAX-TIMEOUT-CALLBACK buffer = %S" buffer) (ein:with-live-buffer buffer (setq ein:query-ajax-canceled 'timeout) (let ((proc (get-buffer-process buffer))) From 91e578e9cc8e9feaa5f2413e54c217666aa6ab0b Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 03:53:51 +0200 Subject: [PATCH 09/11] Correct ein:notebook-querty-timeout-open/save docs --- ein-notebook.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ein-notebook.el b/ein-notebook.el index 4c337ce..c917380 100644 --- a/ein-notebook.el +++ b/ein-notebook.el @@ -121,10 +121,11 @@ yet. So be careful when using EIN functions. They may change." (defcustom ein:notebook-querty-timeout-open (* 60 1000) ; 1 min "Query timeout for opening notebook. If you cannot open large notebook because of timeout error, try -to increase this value. For global setting and more information, -see `ein:query-timeout'." +to increase this value. Setting this value to `nil' means to use +global setting. For global setting and more information, see +`ein:query-timeout'." :type '(choice (integer :tag "Timeout [ms]" 5000) - (const :tag "No timeout" nil)) + (const :tag "Use global setting" nil)) :group 'ein) (defcustom ein:notebook-querty-timeout-save (* 60 1000) ; 1 min @@ -133,7 +134,7 @@ Similar to `ein:notebook-querty-timeout-open', but for saving notebook. For global setting and more information, see `ein:query-timeout'." :type '(choice (integer :tag "Timeout [ms]" 5000) - (const :tag "No timeout" nil)) + (const :tag "Use global setting" nil)) :group 'ein) From 3ef39aa7d469c2b8f4cd94bf20565883937c88be Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 14:59:27 +0200 Subject: [PATCH 10/11] Fixed misplaced ein:notebook-querty-timeout-open/save in doc --- doc/source/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/index.rst b/doc/source/index.rst index 61831e4..0acb838 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -254,8 +254,6 @@ Notebook list .. el:variable:: ein:url-or-port .. el:variable:: ein:default-url-or-port -.. el:variable:: ein:notebook-querty-timeout-open -.. el:variable:: ein:notebook-querty-timeout-save .. el:variable:: ein:scratch-notebook-name-template Notebook @@ -265,6 +263,8 @@ Notebook .. el:variable:: ein:notebook-discard-output-on-save .. el:variable:: ein:notebook-modes .. el:variable:: ein:notebook-kill-buffer-ask +.. el:variable:: ein:notebook-querty-timeout-open +.. el:variable:: ein:notebook-querty-timeout-save .. el:variable:: ein:notebook-console-security-dir .. el:variable:: ein:notebook-console-executable .. el:variable:: ein:notebook-console-args From 9847301a5fa59f4ad5f72df510facaa7cd7a1723 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Thu, 21 Jun 2012 15:03:41 +0200 Subject: [PATCH 11/11] Document ein:query-timeout more --- ein-query.el | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ein-query.el b/ein-query.el index ca71efc..f98effc 100644 --- a/ein-query.el +++ b/ein-query.el @@ -55,12 +55,13 @@ If you do the same operation before the timeout, old operation will be canceled \(see also `ein:query-singleton-ajax'). .. note:: This value exists because it looks like `url-retrieve' - occasionally fails to finish \(start?) querying. To let user - notice that their operation is not finished, timeout is - important. It also prevent opening a lot of useless process - buffers. If you know how to fix the problem with `url-retrieve', - please let me know or send pull request at github! + occasionally fails to finish \(start?) querying. Timeout is + used to let user notice that their operation is not finished. + It also prevent opening a lot of useless process buffers. + You will see them when closing Emacs if there is no timeout. + If you know how to fix the problem with `url-retrieve', please + let me know or send pull request at github! \(Related bug report in Emacs bug tracker: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11469)" :type '(choice (integer :tag "Timeout [ms]" 5000)