-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* implement lock at TaskOnKart.run() * add dump unlock * add redis_fail * add comment * add readme * fix review * move description to docs * fix conflict
- Loading branch information
Showing
9 changed files
with
278 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
1. Task cache collision lock | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Requires | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
You need to install (redis)[https://redis.io/topics/quickstart] for this | ||
advanced function. | ||
|
||
Description | ||
^^^^^^^^^^^ | ||
|
||
Task lock is implemented to prevent task cache collision. (Originally, | ||
task cache collision may occur when same task with same parameters run | ||
at different applications parallelly.) | ||
|
||
1. Set up a redis server at somewhere accessible from gokart/luigi jobs. | ||
|
||
Following will run redis at your localhost. | ||
|
||
.. code:: bash | ||
$ redis-server | ||
2. Set redis server hostname and port number as parameters to gokart.TaskOnKart(). | ||
|
||
You can set it by adding ``--redis-host=[your-redis-localhost] --redis-port=[redis-port-number]`` options to gokart python script. | ||
|
||
e.g. | ||
|
||
.. code:: bash | ||
python main.py sample.SomeTask –local-scheduler –redis-host=localhost –redis-port=6379 | ||
Alternatively, you may set parameters at config file. | ||
|
||
.. code:: | ||
[TaskOnKart] | ||
redis_host=localhost | ||
redis_port=6379 | ||
2. Using efficient task cache collision lock | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
|
||
Description | ||
^^^^^^^^^^^ | ||
|
||
Above task lock will prevent cache collision. However, above setting check collisions only when the task access the cache file (i.e. ``task.dump()``, ``task.load()`` and ``task.remove()``). This will allow applications to run ``run()`` of same task at the same time, which | ||
is not efficent. | ||
|
||
Settings in this section will prevent running ``run()`` at the same time for efficiency. | ||
|
||
1. Set normal cache collision lock Set cache collision lock following ``1. Task cache collision lock``. | ||
|
||
2. Decorate ``run()`` with ``@RunWithLock`` Decorate ``run()`` of yourt gokart tasks which you want to lock with ``@RunWithLock``. | ||
|
||
.. code:: python | ||
from gokart.run_with_lock import RunWithLock | ||
@RunWithLock | ||
class SomeTask(gokart.TaskOnKart): | ||
def run(self): | ||
3. Set ``redis_fail_on_collision`` parameter to true. This parameter will affect the behavior when the task’s lock is taken by other application. By setting ``redis_fail_on_collision=True``, task will be failed if the task’s lock is taken by other application. The locked task will be skipped and other independent task will be done first. If ``redis_fail_on_collision=False``, it will wait until the lock of other application is released. | ||
|
||
The parameter can be set by config file. | ||
|
||
.. code:: | ||
[TaskOnKart] | ||
redis_host=localhost | ||
redis_port=6379 | ||
redis_fail_on_collision=true | ||
4. Set retry parameters. Set following parameters to retry when task | ||
failed. Values of ``retry_count`` and ``retry_delay``\ can be set to | ||
any value depends on your situation. | ||
|
||
:: | ||
|
||
[scheduler] | ||
retry_count=10000 | ||
retry_delay=10 | ||
|
||
[worker] | ||
keep_alive=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from functools import partial | ||
|
||
import luigi | ||
|
||
|
||
class RunWithLock: | ||
def __init__(self, func): | ||
self._func = func | ||
|
||
def __call__(self, instance): | ||
instance._lock_at_dump = False | ||
output_list = luigi.task.flatten(instance.output()) | ||
return self._run_with_lock(partial(self._func, self=instance), output_list) | ||
|
||
def __get__(self, instance, owner_class): | ||
return partial(self.__call__, instance) | ||
|
||
@classmethod | ||
def _run_with_lock(cls, func, output_list: list): | ||
if len(output_list) == 0: | ||
return func() | ||
|
||
output = output_list.pop() | ||
wrapped_func = output.wrap_with_lock(func) | ||
return cls._run_with_lock(func=wrapped_func, output_list=output_list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.