Skip to content

Commit 4903f01

Browse files
authored
Merge branch 'v1.15' into endgame_1.15-updates
2 parents 9f049c3 + ee5e9fe commit 4903f01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1024
-564
lines changed

daprdocs/config.toml

+6-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ id = "G-60C6Q1ETC1"
109109
lang = "en"
110110
[[module.mounts]]
111111
source = "../sdkdocs/rust/daprdocs/content/en/rust-sdk-contributing"
112-
target = "content/contributing/sdks-contrib"
112+
target = "content/contributing/sdk-contrib/"
113113
lang = "en"
114114

115115
[[module.mounts]]
@@ -143,7 +143,11 @@ id = "G-60C6Q1ETC1"
143143
[[module.mounts]]
144144
source = "../translations/docs-zh/translated_content/zh_CN/sdks_js"
145145
target = "content/developing-applications/sdks/js"
146-
lang = "zh-hans"
146+
lang = "zh-hans"
147+
[[module.mounts]]
148+
source = "../translations/docs-zh/translated_content/zh_CN/sdks_rust"
149+
target = "content/developing-applications/sdks/rust"
150+
lang = "zh-hans"
147151
[[module.mounts]]
148152
source = "../translations/docs-zh/translated_content/zh_CN/pluggable-components/dotnet"
149153
target = "content/developing-applications/develop-components/pluggable-components/pluggable-components-sdks/pluggable-components-dotnet"

daprdocs/content/en/concepts/overview.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Dapr exposes its HTTP and gRPC APIs as a sidecar architecture, either as a conta
7676
## Hosting environments
7777

7878
Dapr can be hosted in multiple environments, including:
79-
- Self-hosted on a Windows/Linux/macOS machine for local development
79+
- Self-hosted on a Windows/Linux/macOS machine for local development and in production
8080
- On Kubernetes or clusters of physical or virtual machines in production
8181

8282
### Self-hosted local development

daprdocs/content/en/developing-applications/building-blocks/actors/actors-features-concepts.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ This simplifies some choices, but also carries some consideration:
5757

5858
## Actor communication
5959

60-
You can interact with Dapr to invoke the actor method by calling HTTP/gRPC endpoint.
60+
You can interact with Dapr to invoke the actor method by calling the HTTP endpoint.
6161

6262
```bash
6363
POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/<method/state/timers/reminders>

daprdocs/content/en/developing-applications/building-blocks/actors/actors-timers-reminders.md

+4
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ You can remove the actor reminder by calling
137137
DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/reminders/<name>
138138
```
139139

140+
If an actor reminder is triggered and the app does not return a 2** code to the runtime (for example, because of a connection issue),
141+
actor reminders will be retried up to three times with a backoff interval of one second between each attempt. There may be
142+
additional retries attempted in accordance with any optionally applied [actor resiliency policy]({{< ref "override-default-retries.md" >}}).
143+
140144
Refer [api spec]({{< ref "actors_api.md#invoke-reminder" >}}) for more details.
141145

142146
## Error handling

daprdocs/content/en/developing-applications/building-blocks/conversation/conversation-overview.md

+20-5
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,33 @@ description: "Overview of the conversation API building block"
1010
The conversation API is currently in [alpha]({{< ref "certification-lifecycle.md#certification-levels" >}}).
1111
{{% /alert %}}
1212

13+
Dapr's conversation API reduces the complexity of securely and reliably interacting with Large Language Models (LLM) at scale. Whether you're a developer who doesn't have the necessary native SDKs or a polyglot shop who just wants to focus on the prompt aspects of LLM interactions, the conversation API provides one consistent API entry point to talk to underlying LLM providers.
1314

14-
Using the Dapr conversation API, you can reduce the complexity of interacting with Large Language Models (LLMs) and enable critical performance and security functionality with features like prompt caching and personally identifiable information (PII) data obfuscation.
15+
<img src="/images/conversation-overview.png" width=800 alt="Diagram showing the flow of a user's app communicating with Dapr's LLM components.">
16+
17+
In additon to enabling critical performance and security functionality (like [prompt caching]({{< ref "#prompt-caching" >}}) and [PII scrubbing]({{< ref "#personally-identifiable-information-pii-obfuscation" >}})), you can also pair the conversation API with Dapr functionalities, like:
18+
- Resiliency circuit breakers and retries to circumvent limit and token errors, or
19+
- Middleware to authenticate requests coming to and from the LLM
20+
21+
Dapr provides observability by issuing metrics for your LLM interactions.
1522

1623
## Features
1724

25+
The following features are out-of-the-box for [all the supported conversation components]({{< ref supported-conversation >}}).
26+
1827
### Prompt caching
1928

20-
To significantly reduce latency and cost, frequent prompts are stored in a cache to be reused, instead of reprocessing the information for every new request. Prompt caching optimizes performance by storing and reusing prompts that are often repeated across multiple API calls.
29+
Prompt caching optimizes performance by storing and reusing prompts that are often repeated across multiple API calls. To significantly reduce latency and cost, Dapr stores frequent prompts in a local cache to be reused by your cluster, pod, or other, instead of reprocessing the information for every new request.
2130

2231
### Personally identifiable information (PII) obfuscation
2332

24-
The PII obfuscation feature identifies and removes any PII from a conversation response. This feature protects your privacy by eliminating sensitive details like names, addresses, phone numbers, or other details that could be used to identify an individual.
33+
The PII obfuscation feature identifies and removes any form of sensitve user information from a conversation response. Simply enable PII obfuscation on input and output data to protect your privacy and scrub sensitive details that could be used to identify an individual.
34+
35+
## Demo
36+
37+
Watch the demo presented during [Diagrid's Dapr v1.15 celebration](https://www.diagrid.io/videos/dapr-1-15-deep-dive) to see how the conversation API works using the .NET SDK.
38+
39+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/NTnwoDhHIcQ?si=37SDcOHtEpgCIwkG&amp;start=5444" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
2540

2641
## Try out conversation
2742

@@ -31,7 +46,7 @@ Want to put the Dapr conversation API to the test? Walk through the following qu
3146

3247
| Quickstart/tutorial | Description |
3348
| ------------------- | ----------- |
34-
| [Conversation quickstart](todo) | . |
49+
| [Conversation quickstart](todo) | TODO |
3550

3651
### Start using the conversation API directly in your app
3752

@@ -40,4 +55,4 @@ Want to skip the quickstarts? Not a problem. You can try out the conversation bu
4055
## Next steps
4156

4257
- [How-To: Converse with an LLM using the conversation API]({{< ref howto-conversation-layer.md >}})
43-
- [Conversation API components]({{< ref supported-conversation >}})
58+
- [Conversation API components]({{< ref supported-conversation >}})

daprdocs/content/en/developing-applications/building-blocks/conversation/howto-conversation-layer.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func main() {
9292
}
9393

9494
input := dapr.ConversationInput{
95-
Message: "hello world",
95+
Message: "Please write a witty haiku about the Dapr distributed programming framework at dapr.io",
9696
// Role: nil, // Optional
9797
// ScrubPII: nil, // Optional
9898
}
@@ -134,7 +134,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
134134

135135
let mut client = DaprClient::connect(address).await?;
136136

137-
let input = ConversationInputBuilder::new("hello world").build();
137+
let input = ConversationInputBuilder::new("Please write a witty haiku about the Dapr distributed programming framework at dapr.io").build();
138138

139139
let conversation_component = "echo";
140140

@@ -179,7 +179,7 @@ dapr run --app-id conversation --dapr-grpc-port 50001 --log-level debug --resour
179179
**Expected output**
180180

181181
```
182-
- '== APP == conversation output: hello world'
182+
- '== APP == conversation output: Please write a witty haiku about the Dapr distributed programming framework at dapr.io'
183183
```
184184

185185
{{% /codetab %}}

daprdocs/content/en/developing-applications/building-blocks/jobs/howto-schedule-and-handle-triggered-jobs.md

+100-62
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
type: docs
33
title: "How-To: Schedule and handle triggered jobs"
44
linkTitle: "How-To: Schedule and handle triggered jobs"
5-
weight: 2000
5+
weight: 5000
66
description: "Learn how to use the jobs API to schedule and handle triggered jobs"
77
---
88

@@ -20,7 +20,103 @@ When you [run `dapr init` in either self-hosted mode or on Kubernetes]({{< ref i
2020

2121
In your code, set up and schedule jobs within your application.
2222

23-
{{< tabs "Go" >}}
23+
{{< tabs ".NET" "Go" >}}
24+
25+
{{% codetab %}}
26+
27+
<!-- .NET -->
28+
29+
The following .NET SDK code sample schedules the job named `prod-db-backup`. The job data contains information
30+
about the database that you'll be seeking to backup regularly. Over the course of this example, you'll:
31+
- Define types used in the rest of the example
32+
- Register an endpoint during application startup that handles all job trigger invocations on the service
33+
- Register the job with Dapr
34+
35+
In the following example, you'll create records that you'll serialize and register alongside the job so the information
36+
is available when the job is triggered in the future:
37+
- The name of the backup task (`db-backup`)
38+
- The backup task's `Metadata`, including:
39+
- The database name (`DBName`)
40+
- The database location (`BackupLocation`)
41+
42+
Create an ASP.NET Core project and add the latest version of `Dapr.Jobs` from NuGet.
43+
44+
> **Note:** While it's not strictly necessary
45+
for your project to use the `Microsoft.NET.Sdk.Web` SDK to create jobs, as of the time this documentation is authored,
46+
only the service that schedules a job receives trigger invocations for it. As those invocations expect an endpoint
47+
that can handle the job trigger and requires the `Microsoft.NET.Sdk.Web` SDK, it's recommended that you
48+
use an ASP.NET Core project for this purpose.
49+
50+
Start by defining types to persist our backup job data and apply our own JSON property name attributes to the properties
51+
so they're consistent with other language examples.
52+
53+
```cs
54+
//Define the types that we'll represent the job data with
55+
internal sealed record BackupJobData([property: JsonPropertyName("task")] string Task, [property: JsonPropertyName("metadata")] BackupMetadata Metadata);
56+
internal sealed record BackupMetadata([property: JsonPropertyName("DBName")]string DatabaseName, [property: JsonPropertyName("BackupLocation")] string BackupLocation);
57+
```
58+
59+
Next, set up a handler as part of your application setup that will be called anytime a job is triggered on your
60+
application. It's the responsibility of this handler to identify how jobs should be processed based on the job name provided.
61+
62+
This works by registering a handler with ASP.NET Core at `/job/<job-name>`, where `<job-name>` is parameterized and
63+
passed into this handler delegate, meeting Dapr's expectation that an endpoint is available to handle triggered named jobs.
64+
65+
Populate your `Program.cs` file with the following:
66+
67+
```cs
68+
using System.Text;
69+
using System.Text.Json;
70+
using Dapr.Jobs;
71+
using Dapr.Jobs.Extensions;
72+
using Dapr.Jobs.Models;
73+
using Dapr.Jobs.Models.Responses;
74+
75+
var builder = WebApplication.CreateBuilder(args);
76+
builder.Services.AddDaprJobsClient();
77+
var app = builder.Build();
78+
79+
//Registers an endpoint to receive and process triggered jobs
80+
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5));
81+
app.MapDaprScheduledJobHandler((string jobName, DaprJobDetails jobDetails, ILogger logger, CancellationToken cancellationToken) => {
82+
logger?.LogInformation("Received trigger invocation for job '{jobName}'", jobName);
83+
switch (jobName)
84+
{
85+
case "prod-db-backup":
86+
// Deserialize the job payload metadata
87+
var jobData = JsonSerializer.Deserialize<BackupJobData>(jobDetails.Payload);
88+
89+
// Process the backup operation - we assume this is implemented elsewhere in your code
90+
await BackupDatabaseAsync(jobData, cancellationToken);
91+
break;
92+
}
93+
}, cancellationTokenSource.Token);
94+
95+
await app.RunAsync();
96+
```
97+
98+
Finally, the job itself needs to be registered with Dapr so it can be triggered at a later point in time. You can do this
99+
by injecting a `DaprJobsClient` into a class and executing as part of an inbound operation to your application, but for
100+
this example's purposes, it'll go at the bottom of the `Program.cs` file you started above. Because you'll be using the
101+
`DaprJobsClient` you registered with dependency injection, start by creating a scope so you can access it.
102+
103+
```cs
104+
//Create a scope so we can access the registered DaprJobsClient
105+
await using scope = app.Services.CreateAsyncScope();
106+
var daprJobsClient = scope.ServiceProvider.GetRequiredService<DaprJobsClient>();
107+
108+
//Create the payload we wish to present alongside our future job triggers
109+
var jobData = new BackupJobData("db-backup", new BackupMetadata("my-prod-db", "/backup-dir"));
110+
111+
//Serialize our payload to UTF-8 bytes
112+
var serializedJobData = JsonSerializer.SerializeToUtf8Bytes(jobData);
113+
114+
//Schedule our backup job to run every minute, but only repeat 10 times
115+
await daprJobsClient.ScheduleJobAsync("prod-db-backup", DaprJobSchedule.FromDuration(TimeSpan.FromMinutes(1)),
116+
serializedJobData, repeats: 10);
117+
```
118+
119+
{{% /codetab %}}
24120

25121
{{% codetab %}}
26122

@@ -92,66 +188,8 @@ In this example, at trigger time, which is `@every 1s` according to the `Schedul
92188
}
93189
```
94190

95-
At the trigger time, the `prodDBBackupHandler` function is called, executing the desired business logic for this job at trigger time. For example:
96-
97-
#### HTTP
98-
99-
When you create a job using Dapr's Jobs API, Dapr will automatically assume there is an endpoint available at
100-
`/job/<job-name>`. For instance, if you schedule a job named `test`, Dapr expects your application to listen for job
101-
events at `/job/test`. Ensure your application has a handler set up for this endpoint to process the job when it is
102-
triggered. For example:
103-
104-
*Note: The following example is in Go but applies to any programming language.*
105-
106-
```go
107-
108-
func main() {
109-
...
110-
http.HandleFunc("/job/", handleJob)
111-
http.HandleFunc("/job/<job-name>", specificJob)
112-
...
113-
}
114-
115-
func specificJob(w http.ResponseWriter, r *http.Request) {
116-
// Handle specific triggered job
117-
}
118-
119-
func handleJob(w http.ResponseWriter, r *http.Request) {
120-
// Handle the triggered jobs
121-
}
122-
```
123-
124-
#### gRPC
125-
126-
When a job reaches its scheduled trigger time, the triggered job is sent back to the application via the following
127-
callback function:
128-
129-
*Note: The following example is in Go but applies to any programming language with gRPC support.*
130-
131-
```go
132-
import rtv1 "github.com/dapr/dapr/pkg/proto/runtime/v1"
133-
...
134-
func (s *JobService) OnJobEventAlpha1(ctx context.Context, in *rtv1.JobEventRequest) (*rtv1.JobEventResponse, error) {
135-
// Handle the triggered job
136-
}
137-
```
138-
139-
This function processes the triggered jobs within the context of your gRPC server. When you set up the server, ensure that
140-
you register the callback server, which will invoke this function when a job is triggered:
141-
142-
```go
143-
...
144-
js := &JobService{}
145-
rtv1.RegisterAppCallbackAlphaServer(server, js)
146-
```
147-
148-
In this setup, you have full control over how triggered jobs are received and processed, as they are routed directly
149-
through this gRPC method.
150-
151-
#### SDKs
152-
153-
For SDK users, handling triggered jobs is simpler. When a job is triggered, Dapr will automatically route the job to the
154-
event handler you set up during the server initialization. For example, in Go, you'd register the event handler like this:
191+
When a job is triggered, Dapr will automatically route the job to the event handler you set up during the server
192+
initialization. For example, in Go, you'd register the event handler like this:
155193

156194
```go
157195
...

0 commit comments

Comments
 (0)