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 adopter status to user as string #1207

Merged
merged 7 commits into from
Oct 25, 2023
Merged

add adopter status to user as string #1207

merged 7 commits into from
Oct 25, 2023

Conversation

mwvolo
Copy link
Member

@mwvolo mwvolo commented Oct 13, 2023

No description provided.

@mwvolo mwvolo added the wip label Oct 13, 2023
Copy link
Member

@Dantemss Dantemss left a comment

Choose a reason for hiding this comment

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

I'd say approved but I think update_adopter_status may cause OOM in production. Do we have to load the contacts in chunks? UpdateUserContactInfo only loads contacts modified in the last day for example.

@mwvolo
Copy link
Member Author

mwvolo commented Oct 19, 2023

Thanks, @Dantemss! I knew that was a problem so I through the wip label on here... can you take one more quick glance at it to make sure it looks sane?

@mwvolo mwvolo removed the wip label Oct 19, 2023
@mwvolo mwvolo requested a review from Dantemss October 19, 2023 16:06
Copy link
Member

@Dantemss Dantemss left a comment

Choose a reason for hiding this comment

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

If this task is just for the initial migration and since the change is mainly happening to the local data, I'd reverse it: load 250 users from the local DB that have adopter_status: nil first, then look up their contacts only. This way if you need to stop and resume the process it'll look only at the users that are still missing their adopter_status.

user.adopter_status = contact.adoption_status
user.save!
end
rescue StandardError => se
Copy link
Member

@Dantemss Dantemss Oct 19, 2023

Choose a reason for hiding this comment

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

If this rescues an error, you'll skip up to 250 contacts (the entire batch) which is not great. May be less of a problem if we make this resumable. See above.

Copy link
Member

Choose a reason for hiding this comment

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

I think you can remove the rescue now. Just let it fail if something unexpected happens. Otherwise it can get stuck in an infinite loop.

If it fails, you can always retry.

user = user_by_salesforce_id[contact.id]
user.adopter_status = contact.adoption_status
user.save!
end
Copy link
Member

Choose a reason for hiding this comment

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

I'd wrap each batch inside a separate transaction. I think that will improve performance (rather than using autocommit to automatically create a transaction for each save!).

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is how it's done but let me know if this doesn't look like the correct way to do this.

:accounts_uuid
)
.where(id: users.map(&:salesforce_contact_id))
.index_by(&:id)
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm a little fuzzy on if I did this correctly, will this work properly with line 22 to map the correct contact to the user?

Copy link
Member

Choose a reason for hiding this comment

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

You need to remove .to_a in line 19 below if you want a hashmap.

@mwvolo mwvolo requested a review from Dantemss October 20, 2023 17:31
contacts = contacts.where("Id > '#{last_id}'") unless last_id.nil?
contacts = contacts.to_a
last_id = contacts.last&.id
users = User.where(adopter_status: nil).order(:id).limit(250)
Copy link
Member

Choose a reason for hiding this comment

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

I would say User.where(adopter_status: nil).where.not(salesforce_contact_id: nil).limit(250) here (order(:id) is also fine but optional in this case).

contacts = contacts.to_a
last_id = contacts.last&.id
users = User.where(adopter_status: nil).order(:id).limit(250)
users = users.where("id > #{last_id}") unless last_id.nil?
Copy link
Member

Choose a reason for hiding this comment

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

With the above change you shouldn't need this anymore (or to track last_id). You just find 250 of them and update so adopter_status is not nil and they won't be found in later iterations.

end

updated_users.transaction do
updated_users.save!
Copy link
Member

Choose a reason for hiding this comment

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

I think you need updated_users.each(&:save!)

@mwvolo mwvolo requested a review from Dantemss October 25, 2023 16:22
Copy link
Member

@Dantemss Dantemss left a comment

Choose a reason for hiding this comment

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

Just 2 more things

user.adopter_status = contact.adoption_status
user.save!
end
rescue StandardError => se
Copy link
Member

Choose a reason for hiding this comment

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

I think you can remove the rescue now. Just let it fail if something unexpected happens. Otherwise it can get stuck in an infinite loop.

If it fails, you can always retry.

end
rescue StandardError => se
Sentry.capture_exception se
end
Copy link
Member

Choose a reason for hiding this comment

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

You still need to break out of the loop when there are less than 250 users.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was wondering why this was running for so long locally! Fixed

:accounts_uuid
)
.where(id: users.map(&:salesforce_contact_id))
.index_by(&:id)
Copy link
Member Author

Choose a reason for hiding this comment

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

@Dantemss it looks like index_by is not supported by ActiveForce. I'll see what I can do to fix this.

Copy link
Member

Choose a reason for hiding this comment

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

Try .to_a before .index_by and it should work, since index_by is an array method.

@mwvolo mwvolo requested a review from Dantemss October 25, 2023 20:50
@mwvolo mwvolo merged commit ecdf543 into main Oct 25, 2023
6 checks passed
@mwvolo mwvolo deleted the adopter-status-to-api branch October 25, 2023 21:47
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.

2 participants