Issue 1:
Checklist

I have checked the issues list

for similar or identical enhancement to an existing feature.

I have checked the pull requests list

for existing proposed enhancements.

I have checked the commit log

to find out if the if the same enhancement was already implemented in the

master branch.

I have included all related issues and possible duplicate issues in this issue

(If there are none, check this box anyway).

Brief Summary

I think it would be more convenient to build the documentation using a docker service instead of installing locally the tex* libs. With that the documentation contributors could quickly inspect, build and contribute to the documentation.

Proposed Behavior

It can use the sphinx-autobuild lib to build and serve on port :7000. It won't affect any existing features as far as I am familiar.

Proposed UI/UX

It can be simply like that:

$ docker-compose -f docker/docker-compose.yml run --rm docs make livehtml`

Or it can simply be build & run with an entry point.

$ docker-compose -f docker/docker-compose.yml up --build docs

I've created the service as PoC: https://github.com/syrull/celery/commit/60ae8f1922977c858e9d09ffc6fc6f3dad1c3186

Issue 2:
Checklist

I have checked the issues list

for similar or identical feature requests.

I have checked the pull requests list

for existing proposed implementations of this feature.

I have checked the commit log

to find out if the if the same feature was already implemented in the

master branch.

I have included all related issues and possible duplicate issues

in this issue (If there are none, check this box anyway).

Related Issues and Possible Duplicates

Related Issues

None

Possible Duplicates

None

Brief Summary

Design

A. Implementation

class BeatCallBacl(object):
def __init__(self, func, *args, **kwargs):
self._func = func
self._func_params = {
"args": args,
"kwargs": kwargs
}

def __call__(self):
ret = self._func(*self._func_params["args"], **self._func_params["kwargs"])
LOG.info("beat call: {}, ret:{}".format(self._func.__name__, ret))
return ret

class Scheduler(object):
def apply_async(self, entry, producer=None, advance=True, **kwargs):
# Update time-stamps and run counts before we actually execute,
# so we have that done if an exception is raised (doesn't schedule
# forever.)
entry = self.reserve(entry) if advance else entry
task = self.app.tasks.get(entry.task)

try:
entry_args = [v() if isinstance(v, BeatCallBacl) else v for v in entry.args]
entry_kwargs = {k: v() if isinstance(v, BeatCallBacl) else v for k, v in entry.kwargs.items()}
LOG.info(entry_args)
LOG.info(entry_kwargs)
if task:
return task.apply_async(entry_args, entry_kwargs,
producer=producer,
**entry.options)
else:
return self.send_task(entry.task, entry_args, entry_kwargs,
producer=producer,
**entry.options)
except Exception as exc: # pylint: disable=broad-except
reraise(SchedulingError, SchedulingError(
"Couldn't apply scheduled task {0.name}: {exc}".format(
entry, exc=exc)), sys.exc_info()[2])
finally:
self._tasks_since_sync += 1
if self.should_sync():
self._do_sync()

B. Instructions

beat_schedule = {
'gen_course_records-every-5-minutes': {
'task': 'test',
'schedule': 300,
'kwargs': {
"current": BeatCallBack(datetime.datetime.now)
}
}
}

Architectural Considerations

None

Proposed Behavior

Proposed UI/UX

Diagrams

N/A

Alternatives

None