Skip to content
New issue

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

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

Already on GitHub? # to your account

Scheduled job to send push notifications for Post resource #377

Merged
merged 18 commits into from
Sep 11, 2018

Conversation

enricostano
Copy link
Contributor

@enricostano enricostano commented Jun 4, 2018

WAT

The workflow is the following:

  1. Every time a Post is created or updated we create an Event
  2. For each Event we create as many PushNotification as needed
  3. Every 5 minutes the SendPushNotificationsJob collect all the PushNotification that have not been processed yet and it sends them

Test

  • All members with a mobile device associated to their account will receive a push notification for create and update of offers a inquiries

TODO

@enricostano enricostano added the wip label Jun 4, 2018
@enricostano enricostano self-assigned this Jun 4, 2018
@enricostano enricostano requested review from sauloperez and mllocs June 4, 2018 16:32
Copy link
Collaborator

@sauloperez sauloperez left a comment

Choose a reason for hiding this comment

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

We reduced complexity a great deal now 👏

end

def send
return unless push_notifications.any?
Copy link
Collaborator

Choose a reason for hiding this comment

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

You told me Exponent::Push::Client does not check this and so it blows up if notifications is empty, right? It would make things simpler if they did.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, but they don't :(

push_notifications.map do |push_notification|
{
'to' => push_notification.to,
'title' => push_notification.title
Copy link
Collaborator

Choose a reason for hiding this comment

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

does Exponent::Push::Client requires the keys to be strings? It'd be great if we could use symbols.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be bossible 👍

@@ -0,0 +1,4 @@
send_push_notifications_job:
cron: '*/5 * * * *'
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you remind me the syntax? :trollface:

Copy link
Contributor Author

@enricostano enricostano Jun 6, 2018

Choose a reason for hiding this comment

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

It's every 5 minutes, but we still have to take a decision about this.

add_column :push_notifications, :title, :string, null: false, default: 'Title for existing records'
change_column_default(:push_notifications, :title, nil)
end
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.

The migration will add a DEFAULT first and then remove it to allow the creation of a NOT NULL column on existing records (more info).

@enricostano enricostano force-pushed the feature/scheduled-jobs branch 2 times, most recently from 91626ca to dce49e0 Compare June 12, 2018 15:45
@enricostano enricostano force-pushed the feature/scheduled-jobs branch from 1b6b3f4 to ed4b3a5 Compare June 19, 2018 10:42
Gemfile.lock Outdated
elasticsearch-api (= 1.0.7)
elasticsearch-transport (= 1.0.7)
elasticsearch-api (1.0.7)
elasticsearch (5.0.5)
Copy link
Collaborator

Choose a reason for hiding this comment

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

we need to take extra care about search when we test this PR 🙈


client = Exponent::Push::Client.new

push_notifications.update_all(processed_at: Time.now.utc)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd rather update the processed_at after publishing the notifications just in case that fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We discussed about this and it's simpler this way, push notifications are not really important. You can loose one.

Copy link
Collaborator

@markets markets left a comment

Choose a reason for hiding this comment

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

👍 @enricostano that Push Notifications thing is almost complete no? Maybe we should integrate #381 first (now that we have #356 also merged) and we'll ready to :shipit:

@enricostano
Copy link
Contributor Author

that Push Notifications thing is almost complete no? Maybe we should integrate #381 first (now that we have #356 also merged) and we'll ready to :shipit:

@markets done here #408

@enricostano enricostano force-pushed the feature/scheduled-jobs branch from ed4b3a5 to 5c114f4 Compare August 20, 2018 10:49
@mllocs mllocs self-assigned this Aug 22, 2018
db/schema.rb Outdated
@@ -164,6 +164,7 @@
t.datetime "processed_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title", null: false
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do you need a title? isn't all the info in the Event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to store it in the notification. The Event doesn't understand anything about notifications.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We'll need to do the same for body

queue_as :cron

def perform
push_notifications = PushNotification.where(processed_at: nil)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would filter out old PushNotifications that may not be relevant anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We'll use the processed_at to do that.

Copy link
Collaborator

Choose a reason for hiding this comment

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

validates :event, :device_token, presence: true
validates :event, :device_token, :title, presence: true

def to
Copy link
Collaborator

Choose a reason for hiding this comment

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

ken?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

wat?

PushNotification.create!(
event: event,
device_token: device_token,
title: title
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need to dupe this info? it is already stored in the Event

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it's not. We'll need to do the same for body also.

raise PostError, "HTTP response: #{response.code}, #{response.body}"
end

push_notifications.update_all(processed_at: Time.now.utc)
Copy link
Collaborator

Choose a reason for hiding this comment

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

would you update updated_at as well?

@mllocs
Copy link
Collaborator

mllocs commented Aug 28, 2018

class AddTitleToPushNotification < ActiveRecord::Migration
def up
add_column :push_notifications, :title, :string, null: false, default: 'Title for existing records'
change_column_default(:push_notifications, :title, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why this? We already set a default in the previous line, also we have a not null constrain.

Copy link
Collaborator

Choose a reason for hiding this comment

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

hehehe, this code is yours and was about to ask the same
:D 8069d51#r193443513

Copy link
Contributor Author

Choose a reason for hiding this comment

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

THAT'S IMPOSSIBLE

class AddBodyToPushNotification < ActiveRecord::Migration
def up
add_column :push_notifications, :body, :string, null: false, default: 'Body for existing records'
change_column_default(:push_notifications, :body, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why this? We already set a default in the previous line, also we have a not null constrain.

class AddDataToPushNotification < ActiveRecord::Migration
def up
add_column :push_notifications, :data, :json, null: false, default: '{}'
change_column_default(:push_notifications, :data, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why this? We already set a default in the previous line, also we have a not null constrain.

@mllocs mllocs force-pushed the feature/scheduled-jobs branch from 533545c to bcb8684 Compare September 3, 2018 19:44
@mllocs
Copy link
Collaborator

mllocs commented Sep 3, 2018

The mobile app part: coopdevs/timeoverflow-mobile-app#3

Copy link
Collaborator

@sauloperez sauloperez left a comment

Choose a reason for hiding this comment

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

Looks really good! 👏

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

Successfully merging this pull request may close these issues.

4 participants