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

Implement reminder provider #15

Merged
merged 9 commits into from
Aug 11, 2021
Merged

Conversation

suraciii
Copy link
Contributor

@suraciii suraciii commented Jul 28, 2021

This PR implemented reminder provider based on Redis.

As a reminder table implementation, it needs to support various queries for reminders:

  1. query a single reminder by its grain and name.
  2. query reminders by its grain.
  3. query reminders by a range of grain hash.
  4. query a single reminder by its grain, name and eTag (for removal).

In this implementation, all reminders are stored in a single SortedSet in Redis, and the data of reminder is formatted as serialized JSON array like this:
["$grainHash","$grainRef.ToKeyString()","$reminderName","$eTag","$startAt.ToString("O")","$period.ToString()"]

So that reminders can be queried by following filters:

  1. ["$grainHash","$grainRef.ToKeyString()","$reminderName","
  2. ["$grainHash","$grainRef.ToKeyString()","
  3. ["$grainHashStart"," and ["$grainHashEnd","
  4. ["$grainHash","$grainRef.ToKeyString()","$reminderName","$eTag","

Unfortunately, Redis doesn't support multi-indexes natively, so the data need to be stored in various places to support various queries:
1. in HashSet: $"{serviceId}_{grainRef.ToKeyString()}_{reminderName}", it has two fields ETag and Data, one HashSet only has one reminder's data.
2. in HashSet: $"{serviceId}_{grainRef.ToKeyString()}", it stores all reminders of a grain, reminder names are set as field keys, so that we can query reminders by a grain.
3. in SortedSet: $"{serviceId}_GrainHashIndex", it stores all reminders with grain hashes as scores, so that we can query reminders by a range of grain hash.

@ReubenBond
Copy link
Contributor

Could this be done using a single SortedSet, queried by ZRANGEBYLEX?
The keys, in that case, could take the form: $"{serviceId}_{hashCode:X8}_{grainRef.ToKeyString()}_{reminderName}"

I think your approach is fine, too. Redis is not designed for scalability.

@suraciii
Copy link
Contributor Author

suraciii commented Jul 29, 2021

@ReubenBond I updated it with using a single SortedSet to do this.
Reminders save in the SortedSet with the pattern below:

$"{hashCode:X8}_{grainRef}_{reminderName}:{eTag}:{new {entry.StartAt, entry.Period}}"

But this pattern is quite fragile since any ':' or '_' in reminder name or string-typed grain id will break it. I think using a json array for this may be a better idea, I'll try it later

@suraciii suraciii changed the title WIP: Implement reminder provider Implement reminder provider Aug 3, 2021
@suraciii suraciii marked this pull request as ready for review August 3, 2021 07:02
@ReubenBond
Copy link
Contributor

@suraciii, please let me know when you feel this is ready for final review

@suraciii
Copy link
Contributor Author

suraciii commented Aug 7, 2021

Hi @ReubenBond , It's ready for review now

@ReubenBond ReubenBond merged commit 2a75a03 into OrleansContrib:master Aug 11, 2021
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