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

Add Active Job annotations #191

Merged
merged 1 commit into from
Dec 20, 2023
Merged

Conversation

bdewater
Copy link
Contributor

Type of Change

  • Add RBI for a new gem
  • Modify RBI for an existing gem
  • Other:

Changes

@bdewater bdewater requested a review from a team as a code owner December 18, 2023 16:52
Comment on lines 43 to 52
sig do
type_parameters(:ExceptionType)
.params(
exceptions: T::Class[T.type_parameter(:ExceptionType)],
block: T.nilable(
T.proc.bind(T.attached_class).params(
job: T.attached_class,
error: T.type_parameter(:ExceptionType)
).void
)
).void
end
sig do
params(
exceptions: String,
block: T.nilable(T.proc.bind(T.attached_class).params(job: T.attached_class, error: T.untyped).void),
).void
end
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if there's a policy on Sorbet versions supported. Can make this not use overloads like the methods below, but I wish Sorbet supported overloads with keyword args.

Copy link
Contributor

Choose a reason for hiding this comment

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

👋 Hey Bart, it's been a while. Hope you're well! Jumping in here as it seems a bit off that discard_on is RBI typed differently than rescue_on and retry_on considering according to the Rails docs they're all the same.

Thoughts on bringing discard_on in-line with the others?

Bonus, would allow discard_on usage to avoid needing T.unsafe with the latest Sorbet provided the array of strings is frozen via freeze re: the following change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @larouxn 😄 hope you're doing well too!

You're correct they're all the same but the discard_on sigs are more accurate when the first sig with generics applies. rescue_on and retry_on should ideally follow this example, except for the fact that we currently can't use overloads because of keyword arguments: sorbet/sorbet#37

Copy link
Contributor

Choose a reason for hiding this comment

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

Understood. Assuming Sorbet keyword argument support is fixed, we should update all to use the more accurate overload style approach. Assuming support is not fixed, current state, does it make sense to bring discard_on in line with the other two? In the end, I'm thinking consistency either way would be best, leaning towards non-overload given we don't know when if ever kwarg support will be fixed. 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@larouxn larouxn Jul 19, 2024

Choose a reason for hiding this comment

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

Thanks for taking a look! Hmm, I thought (could be wrong) that making discard_on typed the same as rescue_on and retry_on would make working with frozen arrays of string better. I could be wrong.

For a slight bit more context, in my experience working with latest Sorbet, as of sorbet/sorbet#7993, splatting a frozen array of strings with rescue_on and retry_on is fine, no errors but doing the same with discard_on will lead to an error due to the stricter expectation that all string/non-string classes passed to it are of ExceptionType.

Expected T::Class[T.type_parameter(:ExceptionType)] but found T.class_of(Permanent) for argument exceptions https://srb.help/7002

Thus, it's not a bug, it's expected behaviour. But at the same time, I think it would be clearer if all three ActiveJob methods had the same typing/expectations.

Copy link
Contributor

Choose a reason for hiding this comment

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

Update, seemingly good news, appears we can't leave ExceptionType as is and update the signature below from exceptionsString to T.any(Module, String), like the other two methods. #263 (comment) 🙌

@andyw8
Copy link
Contributor

andyw8 commented Dec 18, 2023

I'll run this against Shopify core to verify.

@andyw8
Copy link
Contributor

andyw8 commented Dec 18, 2023

Verified with:

bin/tapioca annotations --sources=https://raw.githubusercontent.com/bdewater/rbi-central/aj-class-methods

2 new typecheck failures, but just needed a T.bind(self,..) with the retry_on block.

@bdewater
Copy link
Contributor Author

bdewater commented Dec 18, 2023

2 new typecheck failures, but just needed a T.bind(self,..) with the retry_on block.

Thanks for calling that out. E.g. when using retry_on in ApplicationJob, that is self, not any descendant classes (instances passed as the job arg) where the error is raised. I'll push up a fix shortly.

@andyw8
Copy link
Contributor

andyw8 commented Dec 19, 2023

All good now on Shopify core.

sig do
params(
exceptions: T.any(Module, String),
wait: T.any(ActiveSupport::Duration, Integer, Symbol, T.proc.params(executions: Integer).returns(Integer)),
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 I don't see ActiveSupport::Duration in the docs, even though the implementation indicates it should work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

3.seconds is the default value which is a duration? :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, and I now see the examples also use a duration.

sig { params(part_name: T.nilable(T.any(String, Symbol)), block: T.nilable(T.proc.bind(T.attached_class).returns(T.untyped))).void }
def self.queue_as(part_name = nil, &block); end

sig { params(priority: T.untyped, block: T.nilable(T.proc.bind(T.attached_class).returns(T.untyped))).void }
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't priority always an Integer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly I had no idea, I've never used this feature TBH and I wasn't sure if this was backend-specific. Can make the change.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems there's not much documentation or examples for that, so let's keep it as T.untyped.

@andyw8 andyw8 merged commit 9a73c4d into Shopify:main Dec 20, 2023
2 checks passed
@andyw8
Copy link
Contributor

andyw8 commented Dec 20, 2023

Thanks @bdewater!

@bdewater bdewater deleted the aj-class-methods branch December 20, 2023 15:31
@Morriar Morriar added the rbi Change related to RBI annotations label Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rbi Change related to RBI annotations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants