Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem: pause and rescheduler jobs (serialized and deserialized obviously)
Structure
A TGJob
tg_job
is a telegram job and is based on a constructor with 5 args and a APScheduler Jobjob
fieldtg_job = TGJob(callback, data, name, chat_id, user_id)
: the actual callback, data, ecc we settg_job.job =APJob(callback=tg_job.run, args[application], name=name, **job_kwargs)
So the TGJob wraps the APjob setting the application (became the bot context) as parameter for the
tg_job.run
function when the callback will be executed.Serialization
APScheduler so will try to serialize the
job
instance butapplication
is a arg so it would have been serialized. Here we have our implementation ofSQLAlchemyJobStore
in jobstore.py.Adapter of SQLAlchemyJobStore
When a job is going to be serialized we:
tg_job
instantiating theself
of the job callback (tg_job.run remember?) if the tg_job is in memoryjob
args to tg_job parameters[callback, data, name, chat_id, user_id]
so replacing the unique [application
] arg.then the job is serialized, remember with these key fields:
tg_job.run
function literal (reference to the function not the instance obiouvsly)[callback, data, name, chat_id, user_id]
Deserialization
When we want to reschedule or pause an existing job, we get the job:
job
deserializedtg_job = TGGob(job.args)
(5 args)job
args to be 2 (not only application now).tg_job
andapplication
. The first is going to be theself
argument, the second is the standardapplication
argument that we started with before serializationSerialization of a deserialized job
When we come to the serialization step this time we do not have a
tg_job
instance when trying to get theself
from thejob.callback
function literal.__self__ does not exists
.Solution
So get the
tg_job
form the first argument we provided during deserialization that is the instance we need :)