GothenburgBitFactory / tasklib

A Python library for interacting with taskwarrior databases.
http://tasklib.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
147 stars 28 forks source link

infinite loop with recurring task #41

Closed jdietrch closed 8 years ago

jdietrch commented 8 years ago

I start with an empty .task/ directory, except for one simple script in the hooks/ folder:

jdietrch@saturn:~/.task
$ ls -al
total 12
drwxr-xr-x  3 jdietrch jdietrch 4096 Feb  4 11:06 .
drwxr-xr-x 50 jdietrch jdietrch 4096 Feb  4 11:03 ..
drwxr-xr-x  2 jdietrch jdietrch 4096 Feb  4 10:10 hooks
jdietrch@saturn:~/.task
$ ls -al hooks
total 12
drwxr-xr-x 2 jdietrch jdietrch 4096 Feb  4 10:10 .
drwxr-xr-x 3 jdietrch jdietrch 4096 Feb  4 11:06 ..
-rwxr-xr-x 1 jdietrch jdietrch  101 Feb  4 10:10 on-add
jdietrch@saturn:~/.task
$ cat hooks/on-add 
#!/usr/bin/python

from tasklib.task import Task

task = Task.from_input()

print task.export_data()
jdietrch@saturn:~/.task
$ 

Then I add a task:

jdietrch@saturn:~/.task
$ task add "Mow the lawn" due:Sunday recur:weekly
Created task 1.
jdietrch@saturn:~/.task
$ 

Then I run the 'task' command:

jdietrch@saturn:~/.task
$ task

...but it quickly maxes out one of the cores on my CPU and produces a huge number of on-add processes:

jdietrch@saturn:~
$ ps aux | grep on-add | wc -l
71
jdietrch@saturn:~
$

So I kill it with Ctrl-C, which produces the following stacktrace:

jdietrch@saturn:~/.task
$ task
^CTraceback (most recent call last):
  File "/home/jdietrch/.task/hooks/on-add", line 5, in <module>
    task = Task.from_input()
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 239, in from_input
    task._load_data(json.loads(input_file.readline().strip()))
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 64, in _load_data
    self._original_data = copy.deepcopy(self._data)
  File "/usr/lib/python2.7/copy.py", line 163, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python2.7/copy.py", line 257, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/lib/python2.7/copy.py", line 172, in deepcopy
    copier = getattr(x, "__deepcopy__", None)
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/lazy.py", line 31, in __getattr__
    self.replace()
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/lazy.py", line 66, in replace
    replacement = self._tw.tasks.get(uuid=self._uuid)
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 524, in get
    num = len(clone)
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 456, in __len__
    self._result_cache = list(self)
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 461, in __iter__
    self._result_cache = self._execute()
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/task.py", line 493, in _execute
    return self.backend.filter_tasks(self.filter_obj)
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/backends.py", line 303, in filter_tasks
    for line in self.execute_command(args):
  File "/home/jdietrch/.local/lib/python2.7/site-packages/tasklib/backends.py", line 264, in execute_command
    stdout, stderr = [x.decode('utf-8') for x in p.communicate()]
  File "/usr/lib/python2.7/subprocess.py", line 799, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.7/subprocess.py", line 1409, in _communicate
    stdout, stderr = self._communicate_with_poll(input)
  File "/usr/lib/python2.7/subprocess.py", line 1463, in _communicate_with_poll
    ready = poller.poll()
KeyboardInterrupt

jdietrch@saturn:~/.task
$

In case it's helpful, here's some information on tasklib and taskwarrior:

jdietrch@saturn:~/.task
$ pip show tasklib

---
Name: tasklib
Version: 0.12.0
Location: /home/jdietrch/.local/lib/python2.7/site-packages
Requires: six, pytz, tzlocal
jdietrch@saturn:~/.task
$ task diagnostics

task 2.5.0
   Platform: Linux

Compiler
    Version: 4.9.2
       Caps: +stdc +stdc_hosted +LP64 +c8 +i32 +l64 +vp64 +time_t64
 Compliance: C++11

Build Features
      CMake: 3.0.2
    libuuid: libuuid + uuid_unparse_lower
  libgnutls: 3.3.8
 Build type: None

Configuration
       File: /home/jdietrch/.taskrc (found), 1610 bytes, mode 100644
       Data: /home/jdietrch/.task (found), dir, mode 40755
    Locking: Enabled
         GC: Enabled
    $VISUAL: /usr/bin/vim
     Server: 
      Trust: strict
Certificate: , not readable, 0 bytes
        Key: , not readable, 0 bytes
    Ciphers: NORMAL
      Creds: 

Hooks
    Scripts: Enabled
             /home/jdietrch/.task/hooks/on-add (executable)

Tests
      $TERM: screen-256color (172x61)
       Dups: Scanned 1 tasks for duplicate UUIDs:
             No duplicates found

jdietrch@saturn:~/.task
$

If any further information would be helpful, please don't hesitate to ask.

Thank you, James

robgolding commented 8 years ago

Thanks for reporting this @jdietrch, your detailed info meant I could find the root cause pretty quickly :smile:

I have a fix ready, just need to write a test and release a hotfix!

robgolding commented 8 years ago

Just merged this fix and released a new version 0.12.1 - thanks again for the report!