-
Notifications
You must be signed in to change notification settings - Fork 69
Push notifications background job for Post #367
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks quite good to me, besides a few small details I'm happy to postpone my only design concern in an upcoming PR when we have a better understanding of the notifications we need to send. I just left it here for the record.
|
|
||
| raise 'A valid Event must be provided' unless event | ||
|
|
||
| ::PushNotifications::Creator.create!(event: event) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need the leading ::? This reference lives in the global namespace so I don't see why PushNotifications::Creator would have any problem finding the constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just used to it, it makes it easier to ruby to find constants. Especially in Rails the constants lookup can be really "kafkian"...
app/models/push_notification.rb
Outdated
| class PushNotification < ActiveRecord::Base | ||
| belongs_to :event, foreign_key: 'event_id' | ||
|
|
||
| validates_presence_of :event |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, use the (latest) validates syntax instead. We don't know how long the old syntax will be maintained.
| it { is_expected.to validate_presence_of(:event) } | ||
| end | ||
|
|
||
| describe 'Relations' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather name it association which is the convention from Rails. The way I see it we're are testing it from the AR's perspective.
| @@ -0,0 +1,24 @@ | |||
| module PushNotifications | |||
| class EventNotifier | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow why we're nesting this PostLogic here? what's the actual reasoning? What confuses me I think is the fact that EventNotifier is both a class and a namespace 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct, I could have put PostLogic class even in the same file where EventNotifier is defined... but I don't like it much. PostLogic basically is a local business domain, only used inside EventNotifier... at least for now...
| @@ -0,0 +1,24 @@ | |||
| module PushNotifications | |||
| class EventNotifier | |||
| class PostLogic | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would try to find a better name for this. PostLogic is rather vague and as a reader, doesn't tell me much of what to expect from this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't like the name either... but I wanted to move forward... let's think about a better name later.
|
|
||
| # Conditions for Post: | ||
| # - All the members of the associated organization | ||
| # - that have a DeviceToken associated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this second bullet point looks like the continuation of the previous one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll rewrite this doc, it's an AND basically...
|
|
||
| context 'and the user has a DeviceToken associated' do | ||
|
|
||
| before { Fabricate(:device_token, user: user, token: 'aloha') } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the spacing up until here makes it a bit hard to read. I'd simply keep the before's right after their context.
| end | ||
| end | ||
|
|
||
| context 'but the user has not a DeviceToken associated' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| raise 'The resource associated to the Event is not supported' | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, this feels like a Factory. It knows what class to instantiate and but it also delegates #users to the underlying class.
We can avoid this second unnecessary responsibility from EventNotifier by limiting it to return the PostLogic instance. This class is the one that actually implements #users. So something like:
class Creator
def create!
event_notifier = EventNotifierFactory.notification_for(event: event)
event_notifier.users.each do
PushNotification.create!(event: event)
end
end
endThe idea here is that all kinds of event_notifier we come up with conform to the duck-type by implementing #users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we need to play a bit more with the relationship between PostLogic and EventNotifier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at PostLogic class as a way to organize things inside EventNotifier business logic. Users outside EventNotifier shouldn't know anything about it, they just ask #users to EventNotifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks quite good to me, besides a few small details I'm happy to postpone my only design concern for an upcoming PR when we have a better understanding of the notifications we need to send. I just left it here for the record.
9cff2ec to
4dc7d64
Compare
b4b4fcc to
4a493c7
Compare
|
Looks very good 👌 |
ec3dc54 to
0f89488
Compare
0f89488 to
6e64400
Compare
b038ab8 to
a2d4b8c
Compare
|
Tested on staging. |
WAT
Whit this PR we add a new step in the
PostPersisterservice while creating or updating aPost: we also enqueue now aCreatePushNotificationsJob.The background job will retrieve the
Eventand thePostassociated to the event and will create as manyPushNotificationresources as needed.In the case of
Postit will create aPushNotificationfor each user in thePost's organization that have aDeviceToken. In future PRs we'll add this feature forMemberandTransferresources.This PR only creates the
PushNotificationresources, it doesn't send any push notification to the mobile devices yet. The plan is to add a scheduled background job that will send them in batches.What to test
The following workflow:
PushNotificationrecords as the people in the organization with aDeviceTokenTODO
testengine for ActiveJob