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

fix: Always initialize tracer #136

Merged
merged 3 commits into from
Dec 6, 2024
Merged

fix: Always initialize tracer #136

merged 3 commits into from
Dec 6, 2024

Conversation

rustatian
Copy link
Member

@rustatian rustatian commented Dec 6, 2024

Reason for This PR

closes: roadrunner-server/roadrunner#2085

Description of Changes

  • Always initialize tracer (no-op if not configured, but not nil).

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the MIT license.

PR Checklist

[Author TODO: Meet these criteria.]
[Reviewer TODO: Verify that these criteria are met. Request changes if not]

  • All commits in this PR are signed (git commit -s).
  • The reason for this PR is clearly provided (issue no. or explanation).
  • The description of changes is clear and encompassing.
  • Any required documentation changes (code and docs) are included in this PR.
  • Any user-facing changes are mentioned in CHANGELOG.md.
  • All added/changed functionality is tested.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced tracing capabilities for better observability of job processing commands.
    • Introduced a new configuration file for server setup with RPC and job processing parameters.
    • Added a new PHP script for initializing the job processing environment.
  • Bug Fixes

    • Updated task acknowledgment method to improve task processing flow.
    • Fixed a bug in boolean value checks to ensure correct evaluation from configuration.
  • Tests

    • Added a new test case to cover the initialization and shutdown process related to issue 2085.

Signed-off-by: Valery Piashchynski <[email protected]>
@rustatian rustatian added the bug Something isn't working label Dec 6, 2024
@rustatian rustatian requested a review from wolfy-j December 6, 2024 11:43
@rustatian rustatian self-assigned this Dec 6, 2024
Copy link
Contributor

coderabbitai bot commented Dec 6, 2024

Warning

Rate limit exceeded

@rustatian has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 23 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 33d80ea and 13d7705.

Walkthrough

The changes in this pull request enhance the tracing capabilities of the Plugin struct in plugin.go by adding a new tracer field and updating methods to utilize it for command execution tracking. A new YAML configuration file is introduced to set up a server with specific job processing parameters. Additionally, a new test function is added to validate the changes related to issue #2085, and modifications are made to PHP scripts to improve task acknowledgment handling.

Changes

File Change Summary
plugin.go Added tracer *sdktrace.TracerProvider to Plugin struct; updated Init, Serve, and readCommands methods for tracing.
tests/configs/.rr-issue2085.yaml New YAML configuration file created for server setup with RPC and job processing parameters.
tests/jobs_general_test.go Added TestIssue2085 function for testing new job processing initialization and shutdown logic.
tests/php_test_files/jobs/jobs_ok.php Changed task acknowledgment method from complete() to ack() in task processing.
tests/php_test_files/jobs/on-init.php Introduced new PHP script for job processing initialization; added variable declaration and count() method.

Assessment against linked issues

Objective Addressed Explanation
Enhance tracing capabilities to prevent segfaults when using Jobs API (2085)
Ensure proper initialization of job processing before API usage (2085)
Maintain existing functionality of job processing and tracing (2085)

Suggested labels

enhancement

🐇 In the code, I hop with glee,
Tracing jobs as fast as can be!
With YAML set, and tests in line,
RoadRunner's speed is now divine!
Acknowledge tasks, no more delay,
Hopping forward, come what may! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
tests/jobs_general_test.go (2)

150-221: Consider adding explicit verification of initialization order

While the test sets up the environment correctly, it could be enhanced to explicitly verify that the Jobs API remains stable when accessed before full plugin initialization.

Consider adding these verifications:

  1. Add assertions to verify the tracer initialization
  2. Add a test case that attempts to access the Jobs API immediately after startup
  3. Verify no segfault occurs during rapid initialization/shutdown cycles
 func TestIssue2085(t *testing.T) {
     // ... existing setup ...
     
     time.Sleep(time.Second * 5)
+    
+    // Verify immediate Jobs API access doesn't cause segfault
+    t.Run("ImmediateAccess", helpers.PushToPipe("test-1-memory", false, "127.0.0.1:6001", []byte("test")))
+    
+    // Verify tracer initialization
+    assert.NotNil(t, cont.Get("jobs"))
     
     stopCh <- struct{}{}
     wg.Wait()

215-215: Consider reducing sleep duration

The 5-second sleep might be longer than necessary for initialization.

-    time.Sleep(time.Second * 5)
+    time.Sleep(time.Second * 2)
plugin.go (2)

Line range hint 141-144: Consider consolidating tracer initialization

While the defensive nil check is good, having initialization in both Init and Serve suggests we might need to consolidate our initialization strategy. Consider:

  1. Moving all tracer initialization logic to Init
  2. Adding validation in Init to ensure tracer is properly initialized
-	if p.tracer == nil {
-		// noop tracer
-		p.tracer = sdktrace.NewTracerProvider()
-	}

Line range hint 724-773: Critical: Fix potential resource leak in command handling

The error handling in the command processing could lead to resource leaks and has an incorrect Destroy call:

  1. The span.End() calls are scattered and might be missed in error paths
  2. There's an unconditional Destroy call after the switch statement which could double-free resources

Consider refactoring to use defer for span.End() and removing the incorrect Destroy call:

 func (p *Plugin) readCommands() {
	for {
		select {
		case ev := <-p.eventsCh:
			ctx, span := p.tracer.Tracer(spanName).Start(context.Background(), "read_command", trace.WithSpanKind(trace.SpanKindServer))
+			defer span.End()
			p.log.Debug("received JOBS event", zap.String("message", ev.Message()), zap.String("pipeline", ev.Plugin()))
			// message can be 'restart', 'stop'.
			switch ev.Message() {
			case stopStr:
				pipeline := ev.Plugin()
				_, _, err := p.pipelineExists(pipeline)
				if err != nil {
					p.log.Warn("failed to restart the pipeline", zap.Error(err), zap.String("pipeline", pipeline))
-					span.End()
					continue
				}

				err = p.Destroy(context.Background(), pipeline)
				if err != nil {
					p.log.Error("failed to stop the pipeline", zap.Error(err), zap.String("pipeline", pipeline))
				}

				p.log.Info("pipeline was stopped", zap.String("pipeline", pipeline))
			case restartSrt:
				// ... rest of the switch
			}
-			err := p.Destroy(ctx, ev.Plugin())
-			if err != nil {
-				p.log.Error("failed to destroy the pipeline", zap.Error(err), zap.String("pipeline", ev.Plugin()))
-			}
-			span.End()
		case <-p.stopCh:
			return
		}
	}
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9bfa49b and 949a1e0.

⛔ Files ignored due to path filters (1)
  • go.work.sum is excluded by !**/*.sum
📒 Files selected for processing (5)
  • plugin.go (1 hunks)
  • tests/configs/.rr-issue2085.yaml (1 hunks)
  • tests/jobs_general_test.go (1 hunks)
  • tests/php_test_files/jobs/jobs_ok.php (1 hunks)
  • tests/php_test_files/jobs/on-init.php (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/configs/.rr-issue2085.yaml
🔇 Additional comments (5)
tests/php_test_files/jobs/jobs_ok.php (1)

13-17: LGTM: Task acknowledgment logic is correct

The error handling is properly maintained while updating the task completion method from complete() to ack().

tests/php_test_files/jobs/on-init.php (2)

15-19: LGTM: Jobs initialization is properly configured

The Jobs instance is correctly initialized with RPC connection using environment-provided address.


21-21: Verify if count() is the most appropriate method for initialization

While count() works to trigger initialization, consider if there's a more explicit method for this purpose.

✅ Verification successful

Using count() is appropriate in this initialization context

The code is a test file that verifies the basic initialization of the Jobs system. The count() method is a simple, lightweight way to verify that the Jobs instance is properly connected and functional. Since this is a test file specifically for initialization (on-init.php), using count() is appropriate as it:

  1. Provides a basic connectivity check
  2. Doesn't modify any state
  3. Is a minimal operation to verify the Jobs system is responsive
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for alternative initialization methods in the Jobs class
ast-grep --pattern 'class Jobs {
  $$$
  init($$$) {
    $$$
  }
  $$$
}'

Length of output: 75


Script:

#!/bin/bash
# Let's search for the Jobs class implementation and its methods
rg -A 10 "class Jobs" 

# Also search for any usage of count() method
rg "->count\(\)" -A 3

Length of output: 452


Script:

#!/bin/bash
# Let's search for the Jobs class implementation and its methods
rg "class Jobs"

# Also search for any usage of count method with proper escaping
rg "count\(\)"

# Let's also look at the specific test file content
cat "tests/php_test_files/jobs/on-init.php"

Length of output: 476

plugin.go (2)

131-131: LGTM: Defensive tracer initialization added

This change ensures the tracer is always initialized, preventing potential nil pointer dereferences. This directly addresses the segmentation fault issue mentioned in #2085.


Line range hint 1-1: Verify tracer usage across the codebase

Let's verify that all tracer usages have been properly updated to handle the new initialization pattern.

✅ Verification successful

All tracer usages are properly initialized and consistent

Based on the search results, all tracer usages follow a consistent pattern where p.tracer.Tracer() is called to create spans across different operations. There are no nil checks found, indicating that the tracer is properly initialized before use. The tracer is used consistently in:

  • Command handling (plugin.go)
  • RPC operations (rpc.go)
  • Event listening (listener.go)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all tracer usages to ensure proper initialization
rg -A 2 "p\.tracer\." 

# Search for potential nil checks that might indicate missed initialization
ast-grep --pattern 'if $x.tracer == nil { $$$  }'

Length of output: 2030

…ypes

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
pipeline.go (1)

Line range hint 1-1: Changes don't align with PR objectives

The modifications in this file focus on integer parsing behavior, which appears unrelated to the PR's objective of fixing segmentation faults during Jobs API initialization. The changes here could introduce new issues without addressing the core problem described in issue #2085.

Consider:

  1. Focusing on the actual initialization issue in the Jobs API
  2. Removing these unrelated changes to minimize risk
  3. Creating a separate PR if integer parsing changes are needed
🧰 Tools
🪛 golangci-lint (1.62.2)

5-5: File is not goimports-ed

(goimports)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 949a1e0 and 33d80ea.

📒 Files selected for processing (1)
  • pipeline.go (2 hunks)
🔇 Additional comments (2)
pipeline.go (2)

6-6: LGTM: Import addition is appropriate

The addition of the "math" package import is necessary for the integer bounds checking implementation.


94-104: ⚠️ Potential issue

Critical: Potentially breaking changes in integer parsing

The changes to the Int method raise several concerns:

  1. Changing from 64-bit to 32-bit parsing is a potentially breaking change for existing clients that might be using large integers.
  2. The bounds check is redundant since strconv.ParseInt with size 32 already handles this internally.
  3. This change appears unrelated to the PR's objective of fixing segmentation faults in the Jobs API initialization.

Suggested fix:

-			res, err := strconv.ParseInt(v, 10, 32)
+			res, err := strconv.ParseInt(v, 10, 64)
-			if res > math.MaxInt32 || res < math.MinInt32 {
-				// return default if out of bounds
-				return d
-			}

Let's verify if there are any existing uses of large integers that might be affected:

Signed-off-by: Valery Piashchynski <[email protected]>
@rustatian rustatian merged commit 82d1bf2 into master Dec 6, 2024
7 checks passed
@rustatian rustatian deleted the fix/always-init-tracer branch December 6, 2024 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[🐛 BUG]: RoadRunner segfaults if you try to use the Jobs API before the plugin is fully loaded
1 participant