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 ability to configure global Redis namespace prefix #134

Merged
merged 9 commits into from
May 14, 2024

Conversation

dammer
Copy link
Contributor

@dammer dammer commented May 13, 2024

#133

SCAN_UUID=ryhNEB9tD2K8pvZDdNZKnT ./bin/app

Mosquito.configure do |settings|
  settings.redis_url = ENV["REDIS_URL"]? || "redis://localhost:6379/5"
  settings.global_prefix = ENV["SCAN_UUID"]?
end

Redis:

1715597220.661123 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:scheduled:*"
1715597220.962453 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:waiting:*"
1715597220.962801 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:scheduled:*"
1715597221.263722 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:waiting:*"
1715597221.263946 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:scheduled:*"
1715597221.565036 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:waiting:*"
1715597221.565360 [5 127.0.0.1:38410] "keys" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:scheduled:*"

KeyBuilder.build global_prefix, KEY_PREFIX, *parts
else
KeyBuilder.build KEY_PREFIX, *parts
end
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wonderfully done @dammer. Do you think there's a need for both KEY_PREFIX and global_prefix? I can't decide 🤔

If not, it might suffice to simply change what KEY_PREFIX itself means, or how it is sourced:

   # KEY_PREFIX becomes a getter or class getter:
   getter key_prefix : String { Mosquito.configuration.global_prefix }

   # Or just ditch key_prefix altogether and read from configuration:
   def self.build_key(*parts)
      KeyBuilder.build Mosquito.configuration.global_prefix, *parts
   end

   # and in Configuration:
   property key_prefix : String = "mosquito"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, Rob. I made the decision to keep the "mosquito" prefix based on the fact that without it, the cleanup script would affect the entire global key space, and also because not all code references the constant and sometimes uses a direct string value

runner_prefix = "mosquito:runners:"

Additionally, this may allow us to maintain maximum backward compatibility with third parties.
The first option looks like the best solution to me, but since the getter will be cached, won't there be a risk of calling it before the configuration is applied? In this case, we'll need to reset the cached value when we change the global_prefix option in the configuration.

Copy link
Contributor Author

@dammer dammer May 14, 2024

Choose a reason for hiding this comment

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

I simplified my solution a bit by adding Nil handling in the KeyBuilder, which allows removing the condition in build_key and simplifies the solution slightly. I also removed the direct use of "mosquito" without key_build.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

UPD: I noticed an inconsistency when running the PR on the master branch: the periodic job key is not prefixed. Take a look at "mosquito:periodic_jobs:StatusJob", all other keys are okay. Could it be that the Coordinator runs before the configuration?

127.0.0.1:6379[5]> MONITOR
OK
1715696179.556765 [5 127.0.0.1:34060] "select" "5"
1715696179.556848 [5 127.0.0.1:34062] "select" "5"
1715696179.556977 [5 127.0.0.1:34060] "script" "load" "  if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n      return redis.call(\"del\",KEYS[1])\n  else\n      return 0\n  end"
1715696179.557012 [5 127.0.0.1:34062] "script" "load" "  if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n      return redis.call(\"del\",KEYS[1])\n  else\n      return 0\n  end"
1715696179.557088 [5 127.0.0.1:34060] "set" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:coordinator:football" "0e494ddf5ac9522d" "ex" "10" "nx"
1715696179.557137 [5 127.0.0.1:34062] "zrange" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:queues" "0" "-1"
1715696179.557374 [5 127.0.0.1:34076] "select" "5"
1715696179.557636 [5 127.0.0.1:34076] "hget" "mosquito:periodic_jobs:StatusJob" "last_executed_at"
1715696179.557880 [5 127.0.0.1:34062] "hset" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:job_run:1715696179557:8" "enqueue_time" "1715696179557" "type" "status_job" "retry_count" "0"
1715696179.557981 [5 127.0.0.1:34076] "lpush" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:waiting:status_job" "1715696179557:8"
1715696179.558000 [5 127.0.0.1:34076] "zadd" "ryhNEB9tD2K8pvZDdNZKnT:mosquito:queues" "1715696179" "status_job"
1715696179.558063 [5 127.0.0.1:34062] "hset" "mosquito:periodic_jobs:StatusJob" "last_executed_at" "1715696179"

Copy link
Contributor Author

@dammer dammer May 14, 2024

Choose a reason for hiding this comment

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

Yep it is early than configuration

Mosquito::Base.register_job_interval \{{ @type.id }}, \{{ interval }}

fixed e315789

@dammer dammer requested a review from robacarp May 14, 2024 10:36
Copy link
Collaborator

@robacarp robacarp left a comment

Choose a reason for hiding this comment

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

@dammer nice improvements, and well thought out too.

@@ -159,7 +159,7 @@ module Mosquito
time = Time.utc
overdue_job_runs = redis.zrangebyscore(scheduled_q, "0", time.to_unix_ms.to_s).as(Array)

return [] of JobRun unless overdue_job_runs.any?
return [] of JobRun if overdue_job_runs.empty?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Normally, I'd ask for ameba fixes to be submitted separately, just so the changes history doesn't get too muddled. In this case, 👍 and thank you.

runner_prefix = "mosquito:runners:"
Redis.instance.keys("#{runner_prefix}*")
runner_prefix = build_key(LIST_OF_QUEUES_KEY)
Redis.instance.keys("#{runner_prefix}:*")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice improvement. The use of #keys here is still a performance implication and can abuse redis servers regardless of the search string, but that's an unrelated issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps it's possible to use build_key once here, and then cache the value in the getter runner_prefix to improve performance, but I'm not sure.

@robacarp
Copy link
Collaborator

I believe that this test failure on 1.4 is unrelated to this code -- and that 1.4 should probably not be a target anymore.

@robacarp robacarp merged commit 0107dba into mosquito-cr:master May 14, 2024
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants