Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TaskAdmin +readonly_fields "created_at", "updated_at"; fix setup name #118

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

ikvk
Copy link

@ikvk ikvk commented Jan 11, 2022

  1. TaskAdmin +readonly_fields "created_at", "updated_at"
  2. Ignore pycharm files
  3. Let github.com to show "Used by" block at main repo page (setup.name, on my own experience):
    ikvk/imap_tools@f1b2614#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7R16
  4. Try in models.Task.__str__

@ikvk
Copy link
Author

ikvk commented Mar 17, 2023

"used by" block example:

изображение

@ikvk
Copy link
Author

ikvk commented Apr 23, 2024

Dear @amureki , is project support are stopped/dead?

Copy link
Collaborator

@amureki amureki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution!

I feel like, it'd be good to clarify some things here before we proceed; hence, I left some comments.

instance.message.options.get("eta", instance.message.message_timestamp) / 1000
)

"""Estimated time of arrival"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the value of this docstring? It just deciphers a common-known abbreviation, which the function named after.

Copy link
Author

@ikvk ikvk Apr 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First time I took a few moments to decipher it, as I didn't meet her very often. I think it definitely won't hurt

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Estimated time of arrival"""

I would agree with @amureki on this. Lets remove it before merging.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you serious? How can the documentation line interfere?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I conducted a survey among 10 of my colleagues: "I know exactly what the abbreviation ETA stands for." Most of them are engineers. The result: 40% know for sure.

I didn't think I'd have to defend the docstring either.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more argument:
Explicit is better than implicit.
:D

By the way, is "Estimated time of arrival" the correct decoding of ETA?

Comment on lines 66 to 69
try:
return str(self.message)
except Exception as e:
return f'Failed to display Task: {e}'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, this is interesting.

Could you, please, provide some information regarding this?
What kind of exception did you get here and on which conditions?
If this is a valid case, and we'll decide to handle it - then we'd need to document this more and update a test suite to cover it.

Copy link
Author

@ikvk ikvk Apr 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it was a long time ago, the log has already been cleared. I remember that it was for various reasons:

  • When I interfered with the models data.Task during migration
  • Without my participation, maybe it was a bug in dramatiq.
  • On incorrect using dramatiq actor.send, I have not saved example. I think it's somewhere in https://github.com/Bogdanp/dramatiq/issues

If I can find the info, I will definitely let you know. (or the dramatiq project)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you'd happen to find it, I am curious to see. 👍
And yeah, then we can check what'd be the best way to proceed - either in this library, or directly in dramatiq. But without this knowledge, I am afraid, I would not proceed with these lines here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the broken data gets into the database, no matter how, then it actually breaks the admin web page. (we are dealing with bytes in BinaryField)

This edit will avoid 500 errors if the data was suddenly broken. I don't understand your skepticism, security doesn't suffer, performance doesn't suffer either.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, if you felt scepticism in my comments - that was definitely not the intention.

This code might not suffer from security or performance issues, but this is not the point.
We start here, then we end up wrapping every __str__ or __repr__ functions for premature "safety".
But we don't want that, right?
We want to have every line of code meaning something and solving something. And we intend to ensure its function by adding a test case to make sure it won't happen again, and we won't forget about it.

Plus, I think, if we just catch all exceptions here - we'd start ignoring them (as it is kinda handled already, right?), we could accidentally ignore important symptoms leading to this error. So if there is something wrong with bytes in message property - we should handle that bit and not try-catch every place that uses message.

And this is what I am missing here - I do not know the real case that this code change will solve, but it certainly introduces a different behaviour (even though it is a small one).

I hope you could follow me here, and I am sorry, if you still would not agree with my thinking process here, but I truly believe this is only for the good of the project.

Again, I am looking forward to understanding the underlying issue and let's try to solve it in its roots!

Copy link
Author

@ikvk ikvk Apr 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could accidentally ignore important symptoms leading to this error

  • I absolutely agree, I added a message to the log.

The key feature here is that the database cannot guarantee us the encodability of a BinaryField data.
Any byte error will result in 500 at admin web page, no matter how it got into the database.

And I finally found the trace!
I then changed some dramatic settings in the project, but I didn’t log which ones :D

2022-03-10T16:01:44.770354+05:00 job1.stage.int.<mywork>.ru django: Failed to decode message using encoder .
Traceback (most recent call last):
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/message.py", line 102, in decode
return cls(**global_encoder.decode(data))
_pickle.UnpicklingError: invalid load key, '_'.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/brokers/rabbitmq.py", line 511, in __next__
message = Message.decode(body)
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/message.py", line 104, in decode
raise DecodeError("Failed to decode message.", data, e) from e
dramatiq.errors.DecodeError: Failed to decode message.

@amureki
Copy link
Collaborator

amureki commented Apr 26, 2024

Dear @amureki , is project support are stopped/dead?

hey @ikvk !
The actual status of the project is explained here:
#122

It remains minimally maintained, as continuous support of upcoming Python and Django versions, but the reviews are limited (as I'm sadly struggling with finding the time and strength for it).

We are still grateful for the interest and opened PRs, I'll try to deal with them, but please do not expect instant feedback 😅.

@ikvk
Copy link
Author

ikvk commented Apr 26, 2024

Also I suggest to implement white and black lists:
DJANGO_DRAMATIQ_TASKS_NOT_WRITES = ['task_name',]
DJANGO_DRAMATIQ_TASKS_WRITES_ONLY = ['task_name',]
In TaskManager.create_or_update_from_message by "if not: return None"
It is really useful on practice.

Do you agree to this?

I cat put it here or at next MR.

@amureki
Copy link
Collaborator

amureki commented Apr 26, 2024

Also I suggest to implement white and black lists: DJANGO_DRAMATIQ_TASKS_NOT_WRITES = ['task_name',] DJANGO_DRAMATIQ_TASKS_WRITES_ONLY = ['task_name',] In TaskManager.create_or_update_from_message by "if not: return None" It is really useful on practice.

Do you agree to this?

I cat put it here or at next MR.

I'd suggest opening an issue here with a bit more details, as from this description I am not sure, I did follow what exactly you are proposing here.
Does this mean you want to stop certain tasks from being stored in the admin interface?
Any way, let's proceed in a new issue regarding this topic.

Copy link
Collaborator

@andrewgy8 andrewgy8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ikvk,

Thank you for the contribution, and apologies for the delay in reviewing this!

To help move this PR forward, it would be great if you could provide a clearer description of the specific issue you’re addressing. It also looks like this PR might be tackling multiple issues instead of focusing on one.

Would the following description be more accurate for this PR?
Add "created_at" and "updated_at" fields to the Task Admin

If so, could we limit this PR to just the changes related to that and remove any unrelated code? It also seems like a linting issue might have renamed a couple of variables—could you confirm?

Thanks again for your efforts!

instance.message.options.get("eta", instance.message.message_timestamp) / 1000
)

"""Estimated time of arrival"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Estimated time of arrival"""

I would agree with @amureki on this. Lets remove it before merging.

@@ -3,7 +3,7 @@
from django import db
from dramatiq.middleware import Middleware

LOGGER = logging.getLogger("django_dramatiq.AdminMiddleware")
logger = logging.getLogger(__name__)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Any reason for this change? ie. this is potentially a breaking change for people relying on the namespacing of this logger.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logger naming for this place is not ideomatic, there is no reasons to do this like here.
https://docs.python.org/3/library/logging.html

Anyway the log path will be the same here.

A potential problem may look like this: they changed the name of the class and forgot to change it in the logger.

This approach would be logical if you specified a single name for the entire package, for example: "django_dramatiq_all_pain" however, it is obvious from this place that there was no such goal.

@@ -10,6 +11,8 @@
#: The database label to use when storing task metadata.
DATABASE_LABEL = DjangoDramatiqConfig.tasks_database()

logger = logging.getLogger(__name__)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Same issue as above. 😉

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*above

@@ -19,7 +19,7 @@ def rel(*xs):


setup(
name="django_dramatiq",
name="django-dramatiq",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Any reason to change the name of the project?? 🤔

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes,
Let github.com to show "Used by" block at main repo page (setup.name, on my own experience):
For my lib it works, I found this decision somewhere at web.
ikvk/imap_tools@f1b2614#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7R16

Here is rules:
https://packaging.python.org/en/latest/specifications/name-normalization/

This is not killer fature, but useful.

If I saw such a MR for my library, I would also double-check everything 100 times.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let github.com to show "Used by" block at main repo page

I dont think this is the case, and its most likely due to the number of public repo dependents being less than 100..

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe so, I suggest you try, and if anything, you can roll back the changes in the minor release immediately after the release.
In my old screenshot, the number of uses was 500, there is a chance of success.
*The block is not always visible immediately after opening the repository page, sometimes you need to wait a few seconds and refresh the page.

Co-authored-by: Andrew Graham-Yooll <[email protected]>
Comment on lines +69 to +73
try:
return str(self.message)
except Exception as e:
logger.exception(f'Failed to display Task {self.id}')
return f'Failed to display Task: {e}'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what condition would this raise?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I told above

The key feature here is that the database cannot guarantee us the encodability of a BinaryField data.
Any byte error will result in 500 at admin web page, no matter how it got into the database.

And I finally found the trace!
I then changed some dramatic settings in the project, but I didn’t log which ones :D

2022-03-10T16:01:44.770354+05:00 job1.stage.int.<mywork>.ru django: Failed to decode message using encoder .
Traceback (most recent call last):
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/message.py", line 102, in decode
return cls(**global_encoder.decode(data))
_pickle.UnpicklingError: invalid load key, '_'.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/brokers/rabbitmq.py", line 511, in __next__
message = Message.decode(body)
File "/home/int/.pyenv/versions/3.9.7/envs/int-3.9.7/lib/python3.9/site-packages/dramatiq/message.py", line 104, in decode
raise DecodeError("Failed to decode message.", data, e) from e
dramatiq.errors.DecodeError: Failed to decode message.

@ikvk
Copy link
Author

ikvk commented Feb 3, 2025

@andrewgy8 , please summarize this PR to close it, what do I need to do?

@andrewgy8
Copy link
Collaborator

Apologies for the delay. I appreciate your work on this! I noticed that the suggestions from myself and @amureki haven't been addressed yet. Once those are incorporated, I'll be happy to review your changes again.

Thanks!

@ikvk
Copy link
Author

ikvk commented Feb 14, 2025

I would like to discuss your suggestions:

  1. Comment
    """Estimated time of arrival"""
    I have given my arguments, do you disagree with them?
    Honestly, I am confused by this suggestion, why is it important?

  2. logger
    logger = logging.getLogger(__name__)
    Please tell me why it is important to use a non-ideomatic version of the logger here.
    What problem is being solved in this case?

  3. Setup name
    name="django_dramatiq",
    This is a really sensitive change, and it cannot but arouse suspicion.
    I suggest trying to issue a release with a special mark, instead of v0.12.0 put v0.12.0rc1 or v0.12.0_usedby_test.
    If this doesn't work (used by doesn't appear in a couple of days) - you can always remove the release from PyPI and github and return the name back.
    Note that even the library's README.md uses the wording:
    pip install django-dramatiq
    What do you think about this?

Thank you for your attention and answers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants