-
Notifications
You must be signed in to change notification settings - Fork 41
feat: kronos implementation #1001
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,16 +43,21 @@ fn try_update_payload( | |||||||||||||||||||||
| payload_version: PayloadVersion, | ||||||||||||||||||||||
| custom_headers: CustomHeaders, | ||||||||||||||||||||||
| events: Vec<WebhookEvent>, | ||||||||||||||||||||||
| max_retries: i32, | ||||||||||||||||||||||
| description: String, | ||||||||||||||||||||||
| change_reason: String, | ||||||||||||||||||||||
| ) -> Result<UpdateWebhookRequest, String> { | ||||||||||||||||||||||
| if max_retries > 3 { | ||||||||||||||||||||||
| return Err("Max retries must not exceed 3".to_string()); | ||||||||||||||||||||||
|
Comment on lines
+50
to
+51
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+50
to
+52
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate that The validation only checks the upper bound ( 🛡️ Proposed fix to add lower bound validation- if max_retries > 3 {
- return Err("Max retries must not exceed 3".to_string());
- }
+ if max_retries < 0 || max_retries > 3 {
+ return Err("Max retries must be between 0 and 3".to_string());
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| Ok(UpdateWebhookRequest { | ||||||||||||||||||||||
| enabled: Some(enabled), | ||||||||||||||||||||||
| url: Some(NonEmptyString::try_from(url)?), | ||||||||||||||||||||||
| method: Some(method), | ||||||||||||||||||||||
| payload_version: Some(payload_version), | ||||||||||||||||||||||
| custom_headers: Some(custom_headers), | ||||||||||||||||||||||
| events: Some(events), | ||||||||||||||||||||||
| max_retries: Some(max_retries), | ||||||||||||||||||||||
| description: Some(Description::try_from(description)?), | ||||||||||||||||||||||
| change_reason: ChangeReason::try_from(change_reason)?, | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
|
|
@@ -69,6 +74,7 @@ pub fn WebhookForm( | |||||||||||||||||||||
| #[prop(default = PayloadVersion::default())] payload_version: PayloadVersion, | ||||||||||||||||||||||
| #[prop(default = CustomHeaders::default())] custom_headers: CustomHeaders, | ||||||||||||||||||||||
| #[prop(default = Vec::new())] events: Vec<WebhookEvent>, | ||||||||||||||||||||||
| #[prop(default = 3)] max_retries: i32, | ||||||||||||||||||||||
| #[prop(into)] handle_submit: Callback<()>, | ||||||||||||||||||||||
| ) -> impl IntoView { | ||||||||||||||||||||||
| let workspace = use_context::<Signal<Workspace>>().unwrap(); | ||||||||||||||||||||||
|
|
@@ -83,6 +89,7 @@ pub fn WebhookForm( | |||||||||||||||||||||
| let (custom_headers_rs, custom_headers_ws) = create_signal(custom_headers); | ||||||||||||||||||||||
| let (change_reason_rs, change_reason_ws) = create_signal(String::new()); | ||||||||||||||||||||||
| let (events_rs, events_ws) = create_signal(events); | ||||||||||||||||||||||
| let (max_retries_rs, max_retries_ws) = create_signal(max_retries); | ||||||||||||||||||||||
| let (req_inprogess_rs, req_inprogress_ws) = create_signal(false); | ||||||||||||||||||||||
| let update_request_rws = RwSignal::new(None); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -108,6 +115,7 @@ pub fn WebhookForm( | |||||||||||||||||||||
| let custom_headers = custom_headers_rs.get_untracked(); | ||||||||||||||||||||||
| let change_reason = change_reason_rs.get_untracked(); | ||||||||||||||||||||||
| let events = events_rs.get_untracked(); | ||||||||||||||||||||||
| let max_retries = max_retries_rs.get_untracked(); | ||||||||||||||||||||||
| let workspace = workspace.get_untracked().0; | ||||||||||||||||||||||
| let org_id = org.get_untracked().0; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -132,6 +140,7 @@ pub fn WebhookForm( | |||||||||||||||||||||
| payload_version, | ||||||||||||||||||||||
| custom_headers, | ||||||||||||||||||||||
| events, | ||||||||||||||||||||||
| max_retries, | ||||||||||||||||||||||
| description, | ||||||||||||||||||||||
| change_reason, | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
@@ -152,6 +161,7 @@ pub fn WebhookForm( | |||||||||||||||||||||
| payload_version, | ||||||||||||||||||||||
| custom_headers, | ||||||||||||||||||||||
| events, | ||||||||||||||||||||||
| max_retries, | ||||||||||||||||||||||
| change_reason, | ||||||||||||||||||||||
| &workspace, | ||||||||||||||||||||||
| &org_id, | ||||||||||||||||||||||
|
|
@@ -295,6 +305,25 @@ pub fn WebhookForm( | |||||||||||||||||||||
| /> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <div class="form-control"> | ||||||||||||||||||||||
| <Label | ||||||||||||||||||||||
| title="Max Retries" | ||||||||||||||||||||||
| description="Number of retry attempts on failure (0–3)." | ||||||||||||||||||||||
| /> | ||||||||||||||||||||||
| <Input | ||||||||||||||||||||||
| placeholder="Max Retries" | ||||||||||||||||||||||
| class="input input-bordered w-full max-w-md" | ||||||||||||||||||||||
| value=Value::Number(serde_json::Number::from(max_retries_rs.get_untracked())) | ||||||||||||||||||||||
| schema_type=Single(JsonSchemaType::Integer) | ||||||||||||||||||||||
| r#type=InputType::Integer | ||||||||||||||||||||||
| on_change=Callback::new(move |value: Value| { | ||||||||||||||||||||||
| if let Some(n) = value.as_i64() { | ||||||||||||||||||||||
| max_retries_ws.set(n as i32); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+319
to
+322
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add bounds checking before casting i64 to i32. The code casts 🛡️ Proposed fix to validate range before cast on_change=Callback::new(move |value: Value| {
if let Some(n) = value.as_i64() {
- max_retries_ws.set(n as i32);
+ if n >= 0 && n <= 3 {
+ max_retries_ws.set(n as i32);
+ }
}
})This validates the range before updating the signal, ensuring only valid values (0–3) are accepted. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| /> | ||||||||||||||||||||||
| </div> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| <div class="form-control gap-3"> | ||||||||||||||||||||||
| <Label | ||||||||||||||||||||||
| title="Custom Headers" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
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.
🧩 Analysis chain
🏁 Script executed:
Repository: juspay/superposition
Length of output: 195
🏁 Script executed:
Repository: juspay/superposition
Length of output: 715
🏁 Script executed:
Repository: juspay/superposition
Length of output: 583
🏁 Script executed:
Repository: juspay/superposition
Length of output: 90
🏁 Script executed:
Repository: juspay/superposition
Length of output: 46
🏁 Script executed:
Repository: juspay/superposition
Length of output: 206
🏁 Script executed:
Repository: juspay/superposition
Length of output: 3612
🏁 Script executed:
Repository: juspay/superposition
Length of output: 46
🏁 Script executed:
Repository: juspay/superposition
Length of output: 297
🏁 Script executed:
Repository: juspay/superposition
Length of output: 1608
🏁 Script executed:
Repository: juspay/superposition
Length of output: 82
🌐 Web query:
kronos-worker kronos-common crates.io rust💡 Result:
kronos-worker and kronos-common are internal Rust crates from the Juspay Kronos project, a distributed job scheduling and execution system. They are not published on crates.io but are part of the monorepo at https://github.com/juspay/kronos [1]. kronos-common: Shared library providing models, database layer, configuration, tenant management, caching, and metrics [1]. kronos-worker: Execution engine that polls the database for queued, retrying, or pending job executions, resolves templates, dispatches to endpoints (including Kafka and Redis Streams via feature flags), and exposes metrics via HTTP [1]. The project includes other crates like kronos-api (REST API server with Actix-web), kronos-mock-server (test fixture), and kronos-dashboard (Leptos/WASM web UI). Build with features for dispatchers: cargo build --workspace --features kronos-worker/kafka [1]. No crates.io pages found for these exact names; they appear to be private/internal to the Juspay repo [1][all searches]. Juspay develops open-source Rust projects like Hyperswitch, and Kronos fits as a job scheduler [2][3].
Citations:
Add kronos as a git submodule or update the path dependency.
The path dependencies for
kronos-workerandkronos-commonat lines 94–95 point to../kronos/crates/workerand../kronos/crates/common, which do not exist in the repository. The kronos project is a separate monorepo at https://github.com/juspay/kronos and is not published on crates.io, so path dependencies must be resolved.Options:
../kronos(relative to superposition)🤖 Prompt for AI Agents