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

Review result reaction #111

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

ruokun-niu
Copy link
Contributor

@ruokun-niu ruokun-niu commented Nov 7, 2024

Description

The result reaction is used to retrieve the current result set, or the result set at a given timestamp.

To retrieve the current result set, send a GET request to the endpoint /{query_id}, where query_id is the query you are interested in.

For example:

curl -X GET "localhost:8080/hello-world-from"

To retrieve the result set at a given timestamp, send a GET request to the endpoint /{query_id}/{timestamp}, where query_id is the query you are interested in, and timestamp is the timestamp you are interested in. (This requires the retentionPolicy of the continuous query to be set to all or expire
For example:

curl -X GET "localhost:8080/hello-world-from/123456789"

Sample output can be found here: https://gist.github.com/ruokun-niu/f5be829bdc6c82e332e99725c923a5e2

Type of change

  • This pull request fixes a bug in Drasi and has an approved issue (issue link required).

Fixes: #issue_number

@@ -37,7 +37,7 @@
drasi wait reaction quick-result-reaction -t 120

# Run the kubectl command and capture the output
$initial_output = & kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -s http://quick-result-reaction-gateway:8080/quick-query/all' 2>$null
$initial_output = & kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -X GET -s http://quick-result-reaction-gateway:8080/quick-query' 2>$null

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning test

Insecure URL
@@ -72,7 +72,7 @@

Start-Sleep -Seconds 20

$final_output = & kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -s http://quick-result-reaction-gateway:8080/quick-query/all' 2>$null
$final_output = & kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -X GET -s http://quick-result-reaction-gateway:8080/quick-query' 2>$null

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning test

Insecure URL
@@ -37,7 +37,7 @@
drasi wait reaction quick-result-reaction -t 120

# Initial result
initial_output=$(kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -s http://quick-result-reaction-gateway:8080/quick-query/all' 2>/dev/null)
initial_output=$(kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -X GET -s http://quick-result-reaction-gateway:8080/quick-query' 2>/dev/null)

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning test

Insecure URL
@@ -56,7 +56,7 @@
echo "Retrieving the current result from the debug reaction"
sleep 20

final_output=$(kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -s http://quick-result-reaction-gateway:8080/quick-query/all' 2>/dev/null)
final_output=$(kubectl run curl-pod --image=curlimages/curl -n $namespace --restart=Never --rm --attach -q -- sh -c 'curl -X GET -s http://quick-result-reaction-gateway:8080/quick-query' 2>/dev/null)

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning test

Insecure URL
@ruokun-niu ruokun-niu marked this pull request as ready for review November 8, 2024 00:19
@ruokun-niu ruokun-niu requested a review from a team as a code owner November 8, 2024 00:19

// Adding an endpoint that supports retrieving all results
app.MapGet("/{queryId}/all", async (string queryId) =>
app.MapGet("/{queryId}", async (string queryId) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

You could make this support large results really easily by adding support for streaming results, but return an IAsyncEnumerable - https://anthonygiretti.com/2021/09/22/asp-net-core-6-streaming-json-responses-with-iasyncenumerable-example-with-angular/

Copy link
Contributor

Choose a reason for hiding this comment

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

resultViewClient.GetCurrentResult already returns a IAsyncEnumerable, so you could just simply return the result of that method.

Copy link
Contributor Author

@ruokun-niu ruokun-niu Nov 15, 2024

Choose a reason for hiding this comment

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

Hi @danielgerlag , I have updated the endpoints to return an IAsyncEnumerable, but I realized that if we just return this it will also return the metadata. I think that sometimes users would just want to get the data (for example in the quick test), so I have created two additional routes: /{queryId}/data and /{queryId}/{ts}/data that just returns the data as IAsyncEnumerable<JsonElement>.

# Timestamp with only the data
ruokunniu ~/Documents/playground  $ curl -X GET "localhost:8080/hello-world-from/12323423423232/data"
[{"MessageFrom":"Brian Kernighan","MessageId":2},{"MessageFrom":"Allen","MessageId":5},{"MessageFrom":"Allen","MessageId":6},{"MessageFrom":"Allen","MessageId":7}]%        
# Timestamp                                                            
ruokunniu ~/Documents/playground  $ curl -X GET "localhost:8080/hello-world-from/12323423423232"     
[{"header":{"sequence":10,"timestamp":1731703800526,"state":"running"}},{"data":{"MessageFrom":"Brian Kernighan","MessageId":2}},{"data":{"MessageFrom":"Allen","MessageId":5}},{"data":{"MessageFrom":"Allen","MessageId":6}},{"data":{"MessageFrom":"Allen","MessageId":7}}]%  
# regular query                                                                           
ruokunniu ~/Documents/playground  $ curl -X GET "localhost:8080/hello-world-from"               
[{"header":{"sequence":10,"timestamp":1731703800526,"state":"running"}},{"data":{"MessageFrom":"Brian Kernighan","MessageId":2}},{"data":{"MessageFrom":"Allen","MessageId":5}},{"data":{"MessageFrom":"Allen","MessageId":6}},{"data":{"MessageFrom":"Allen","MessageId":7}}]%   
# query with data                                                                          
ruokunniu ~/Documents/playground  $ curl -X GET "localhost:8080/hello-world-from/data"
[{"MessageFrom":"Brian Kernighan","MessageId":2},{"MessageFrom":"Allen","MessageId":5},{"MessageFrom":"Allen","MessageId":6},{"MessageFrom":"Allen","MessageId":7}]%      

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll update the quick test based on this

reactions/platform/result-reaction/Program.cs Fixed Show fixed Hide fixed
reactions/platform/result-reaction/Program.cs Fixed Show fixed Hide fixed
Stream? stream = null;
try
{
stream = await _httpClient.GetStreamAsync($"http://{queryContainerId}-view-svc/{queryId}", cancellationToken);

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning

Insecure URL
Stream? stream = null;
try
{
stream = await _httpClient.GetStreamAsync($"http://{queryContainerId}-view-svc/{queryId}?timestamp={ts}", cancellationToken);

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning

Insecure URL
<PackageReference Include="Dapr.AspNetCore" Version="1.10.0" />
<PackageReference Include="Dapr.Client" Version="1.10.0" />
<PackageReference Include="Dapr.AspNetCore" Version="1.14.0" />
<PackageReference Include="Dapr.Client" Version="1.14.0" />
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove all the Dapr libraries.

var builder = WebApplication.CreateBuilder(args);
var configuration = BuildConfiguration();

var queryContainerId = configuration["QueryContainerId"] ?? "default";
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this one of the reaction config properties?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the result reaction does not use the NuGet Reaction SDK, I did not modify how it retrieves the query container ID.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this was originally a hack. If we keep it, we need to document this as a config property and that only queries within that container would work.

var app = builder.Build();
app.UseRouting();

app.Urls.Add("http://0.0.0.0:80"); //dapr
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have the dapr endpoint and query endpoint hosted by 2 different web servers within the app. The query endpoint will be exposed to the public, and if you call it with the right routes, you can pretend to be the dapr side car.

reactions/platform/result-reaction/Program.cs Show resolved Hide resolved
app.Urls.Add("http://0.0.0.0:8080"); //app

// Dapr server
var daprBuilder = WebApplication.CreateBuilder(args);
var daprApp = daprBuilder.Build();
Copy link
Contributor

Choose a reason for hiding this comment

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

Which app side dapr APIs are we implementing for this reaction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm I don't think we are implementing anything for this reaction? Was there something specific that stood out to you?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we aren't implementing any app side dapr APIs, then we don't need to have an open port for it at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right good point. I just removed this and pointed dapr to the app port 8080

Copy link
Contributor

Choose a reason for hiding this comment

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

i think we can just remove the dapr app port?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep that's what I did. I meant that I had to configure the port in the reaction provider, otherwise the sidecar container will fail to start

Copy link
Contributor

Choose a reason for hiding this comment

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

I think if no app port is specified, then the sidecar will not try to connect to the app, and the sidecar should always start?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the issue with not setting an app port is that by default port 80 is used as the app port in the k8s provider (https://github.com/drasi-project/drasi-platform/blob/main/control-planes/kubernetes_provider/src/spec_builder/reaction.rs#L155).

One possible approach is to update this section of code and use None as the default value (indicating that we do not want sidecar to be enabled for this particular reaction). Although this might require changes in other reactions/reactionproviders. Perhaps this could be a separate task @danielgerlag ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point, I think that's out of scope for this PR... let's circle back later.

var app = builder.Build();
app.UseRouting();

app.Urls.Add("http://0.0.0.0:8080"); //app

Check warning

Code scanning / devskim

An HTTP-based URL without TLS was detected. Warning

Insecure URL
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