-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit from GitHub Actions (Generate Post)
- Loading branch information
1 parent
ab6fa25
commit fcf1f46
Showing
3 changed files
with
198 additions
and
1 deletion.
There are no files selected for viewing
99 changes: 99 additions & 0 deletions
99
...ntent/posts/exploring-advanced-server-side-event-streaming-with-warp-in-rust.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
--- | ||
title: "Exploring Advanced Server-Side Event Streaming with Warp in Rust" | ||
date: 2023-09-14T01:25:36.741Z | ||
tags: ["rust","warp","server-side events"] | ||
authors: ["gpt-4"] | ||
--- | ||
|
||
## Introduction | ||
|
||
The Warp framework is one of Rust's leading web server frameworks, allowing developers to build high-performance, safe, and concurrent web applications. One of the many features it provides is server-side event (SSE) streaming, which is a simple, effective way to push real-time updates from the server to the client over HTTP. In this post, we will deep dive into the details of server-side event streaming with Warp in Rust. | ||
|
||
## Prerequisites | ||
|
||
To follow along with this post, you should have: | ||
|
||
- Basic understanding of Rust programming language | ||
- Familiarity with HTTP | ||
- Basic understanding of the concept of server-sent events | ||
|
||
## Warp Server and SSE Handling | ||
|
||
To start with, let's first set up the Warp server and handle incoming requests with an SSE endpoint. | ||
|
||
```rust | ||
use warp::Filter; | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let sse_route = warp::path("sse") | ||
.and(warp::ws()) | ||
.map(|ws: warp::ws::Ws| { | ||
ws.on_upgrade(|websocket| { | ||
// Eliide function logic for now | ||
}) | ||
}); | ||
|
||
let routes = sse_route; | ||
|
||
warp::serve(routes) | ||
.run(([127, 0, 0, 1], 3030)) | ||
.await; | ||
} | ||
``` | ||
|
||
Here, we define an endpoint at `/sse` which upgrade the connection to WebSocket. | ||
|
||
## Handling Event Streams | ||
|
||
Warp offers a clean and convenient API for streaming server-sent events. Let's explore how we can define our server to start streaming events. | ||
|
||
```rust | ||
use futures::{stream::Stream, StreamExt}; | ||
use std::{convert::Infallible, time::Duration}; | ||
use tokio::time::interval; | ||
use warp::Filter; | ||
|
||
async fn event_stream() -> Result<impl Stream<Item = Result<warp::sse::Event, warp::Error>> + Send + 'static, Infallible> { | ||
let mut counter: u64 = 0; | ||
let mut interval = interval(Duration::from_secs(1)); | ||
|
||
let event_stream = async_stream::stream! { | ||
while let Some(_) = interval.next().await { | ||
counter += 1; | ||
|
||
let json_payload = serde_json::json!({ | ||
"counter": counter, | ||
}); | ||
|
||
yield Ok(warp::sse::Event::default() | ||
.data(serde_json::to_string(&json_payload).unwrap()) | ||
.id(counter.to_string()) | ||
.event("message")); | ||
} | ||
}; | ||
|
||
Ok(event_stream) | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let routes = warp::path("sse") | ||
.and_then(event_stream) | ||
.map(|stream| { | ||
warp::sse::reply(warp::sse::keep_alive().stream(stream)) | ||
}); | ||
|
||
warp::serve(routes) | ||
.run(([127, 0, 0, 1], 3030)) | ||
.await; | ||
} | ||
``` | ||
|
||
Here, we define a function `event_stream` which returns a stream of SSE events every 1 second. Then we add it to our Warp routes, converting that stream into an HTTP response with `warp::sse::reply`. | ||
|
||
## Conclusion | ||
|
||
The Warp framework offers an intuitive and easy-to-use framework for Rust developers to create server-sent events. With its high-performance and type-safe nature, we can ensure our SSE server handles incoming requests efficiently while preventing common runtime errors. | ||
|
||
There's a lot more to Warp which we couldn't cover in this post, such as error handling, path parameters, request filtering, and much more. I encourage you to explore more about Warp. Feel confident in Warp's ability to handle SSEs effectively and efficiently. |
86 changes: 86 additions & 0 deletions
86
site/data/completions/exploring-advanced-server-side-event-streaming-with-warp-in-rust.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
{ | ||
"model": "gpt-4", | ||
"prompt": [ | ||
{ | ||
"role": "user", | ||
"content": "You are the author of a personal technical blog about software engineering and computer science subjects." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "New topics for blog posts should be based off of the technical skills, experience, and interests presented in the following resume:\n+++\ntitle = \"Résumé\"\ndescription = \"Derek Cuevas' Résumé\"\ndate = \"2023-06-11\"\nor = \"Derek Cuevas\"\n+++\n\n# Derek Cuevas\n\n[GitHub](https://github.com/derekcuevas) (contact email in bio) \n\n---\n\n## Summary\n\nSenior Software Engineer with 8 years of professional experience, specializing in systems software engineering and low-latency, real-time product development.\n\nExperienced in leading teams and delivering Emmy award-winning projects. Passionate about functional programming and building high performance real-time systems. Skilled in a variety of programming languages and technologies with expertise in [Rust](https://www.rust-lang.org/) and [TypeScript](https://www.typescriptlang.org/).\n\n---\n\n## Programming Languages\n\n- **Proficient:** Rust, TypeScript (& JavaScript), Clojure, Elm\n- **Experienced:** Swift, Elixir, Objective-C, SQL\n\n---\n\n## Technologies, Skills, and Interests\n\n- **Rust:** Tokio, Futures, Hyper, Actix, Warp\n- **Platforms and Services:** AWS, Docker, PostgreSQL, Redis, Apache Pulsar, RabbitMQ, Prometheus, GitLab CI/CD, Node.js, Deno, HTML & CSS\n- **Tooling:** Git, Vim, Bash\n- **Frameworks:** React, React Native, Redux, RxJs, SwiftUI, Phoenix\n- **Protocols:** HTTP, GraphQL, WebSockets, ØMQ, Pub/Sub, JSON, MessagePack, Protobuf, FlatBuffers\n- **Paradigms:** Functional Programming, Real-time Systems\n\n---\n\n## Professional Experience\n\n### Senior Software Engineer II (Lead), Second Spectrum (acquired by Genius Sports)\n(*January 2021 - Current*)\n\n[https://geniussports.com/](https://geniussports.com/)\n\n- Technical lead for the \"Real-time Augmentation Engine\" project's system team, developing low-latency and real-time augmented reality experiences for live TV broadcasters of sporting events.\n- Led the development and integration of core systems using `Rust`, `Tokio`, `MPSC channels`, `FFmpeg`, and `Pulsar`.\n- Oversaw operational management and monitoring systems, release management, simulation systems, and data ingestion/export pipelines.\n- Optimized the overall pipeline for 60fps real-time rendering over high definition broadcast feeds.\n- Key contributor to projects recognized with multiple Emmy awards, including the prestigious [George Wensel Technical Achievement Award](https://geniussports.com/customer-stories/cbs-and-genius-win-sports-emmy-for-romovision/) and Amazon's [Outstanding Interactive Experience](https://www.aboutamazon.com/news/entertainment/thursday-night-football-on-prime-video-wins-sports-emmy-award) at the `Sports Emmys`.\n\n### Senior Software Engineer I (Lead), Second Spectrum\n(*January 2019 - January 2021*)\n\n[https://www.secondspectrum.com/](https://www.secondspectrum.com/)\n\n- Led a team in designing and developing the company's first `GraphQL` service serving as a unified gateway for various microservices. Built upon the `Apollo` server framework leveraging `Node.js`, `TypeScript`, `PostgreSQL`, and `Redis` for caching and pub/sub.\n- Developed a dashboard built with `Three.js` for visualizing 3D player tracking datasets and highlighting data discrepancies.\n- Created a prototype `iOS` application for video highlights using `Swift`, `SwiftUI`, and the `Combine` framework.\n- Mentored interns and fellow engineers, fostering collaboration and knowledge sharing.\n\n### Software Engineer, Second Spectrum\n(*August 2016 - January 2019*)\n\n[https://www.secondspectrum.com/](https://www.secondspectrum.com/)\n\n- Developed the operational and quality assurance management application for the company's optical player tracking system. Stack included `Elixir` (with the `Phoenix` framework), `React`, and heavy use of `WebSockets` to sync and display corrections to operators in near real-time.\n- Improved operator efficiency by 100% through the implementation of an automated task selection system.\n- Led the development of the LA Clipper's live streaming web and mobile application \"Clippers CourtVision\". Stack included `Elm` for the web front-end and `React Native` for the mobile app.\n\n### Software Engineer Intern, MindGraph Medical\n(*September 2015 - January 2016*)\n\n- Designed, developed, and deployed the MindGraph Medical website using `Node.js`, `jQuery`, and `Bootstrap`.\n\n---\n\n## Education\n\n**B.S. Computer Science, San Diego State University, San Diego**\n\n(*Class of 2016*)\n\n- [Advanced Certificate in Web and Mobile Applications Development](https://cs.sdsu.edu/about/)\n\n---\n\n## Personal Projects\n\n- [FYGT](https://github.com/DerekCuevas/derekcuevas.github.io): An experimental blog built with `Hugo`, `Deno`, and `ChatGPT`.\n- [Advent of Code 2022](https://github.com/DerekCuevas/advent-of-code-2022): Solutions to Advent of Code programming problems using functional approaches in `Clojure`.\n- [Interview Cake Algorithms Problem Set](https://github.com/DerekCuevas/interview-cake-clj): Solutions to the interview cake programming problems also by exploring functional approaches in `Clojure`.\n- [Friend List](https://github.com/DerekCuevas/friend-list): A non-trivial programming challenge exploring asynchronous side effects with different programming patterns.\n- [Redux Meta Reducer](https://github.com/DerekCuevas/redux-meta-reducer): A `Redux` higher-order reducer for simplifying the state of fetched data.\n- [Avowal](https://github.com/DerekCuevas/avowal): An asynchronous form validation library for `JavaScript`.\n" | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Your previous 60 posts include: \"Deep Dive Into Postgres and JSONB: Advanced Performance Techniques\", \"Exploring Elm Architecture: Building a SPA with Elm\", \"Exploring Functional Programming with Rust: An Introduction to Frunk\", \"Streamlining High-Performance Concurrency with Rust's Mio Crate\", \"Implementing A Concurrency Safe CRDT Set in Rust\", \"Leveraging Actix for High-Performance Web Services in Rust\", \"Mastering Dependency Injection in Rust: A Comprehensive Guide\", \"Demystifying the World of NATS Messaging System\", \"Mastering Lenses in Swift: A Comprehensive Guide\", \"Deep Dive into Pulsar's Schema Registry\", \"Mastering the Decorator Pattern in TypeScript: Best Practices and Examples\", \"Exploring the Benefits of Declarative Programming in React\", \"Understanding CQRS and Event Sourcing: A Comprehensive Guide\", \"Mastering Apache Flink for Stream Processing\", \"Demystifying Rust's Ownership Model: A Comprehensive Guide\", \"Mastering Java Generics: A Comprehensive Guide\", \"Mastering Reactive Programming with RxJS: Advanced Techniques\", \"A Comprehensive Guide to Threading in Rust\", \"Mastering the Observer Pattern with Rust\", \"Exploring the Power of Rust's Ownership Model: A Comprehensive Guide\", \"The Power of Rust's Clippy: A Comprehensive Guide\", \"Exploring the Disadvantages of Promises in JavaScript\", \"Exploring the Fundamentals of Tail-Call Optimization in JavaScript\", \"Mastering Distributed Systems with Apache BookKeeper\", \"Exploring the Power of Rust's Type System: A Comprehensive Guide\", \"Mastering Asynchronous Event-Driven Architecture with Apache Kafka\", \"Advanced Techniques for Distributed System Design using Apache Cassandra\", \"Exploring the Underlying Architecture of TypeScript\", \"Functional Reactive Programming with Elm: A Comprehensive Guide\", \"Exploring the Power of Clojure's Persistent Data Structures\", \"The Power of Rust's Multithreading Library: rayon\", \"The Power of the `async` Keyword in Rust: A Comprehensive Guide\", \"Mastering Cache Invalidation Strategies: A Comprehensive Guide\", \"Mastering Rust's Serialization and Deserialization: A Comprehensive Guide\", \"Mastering AWS S3 for High Availability: A Comprehensive Guide\", \"Exploring the Fundamentals of Reactive Programming\", \"Mastering Rust's Pinning: An Advanced Guide\", \"Understanding Higher Order Functions in TypeScript\", \"Mastering Async/Await in TypeScript: A Comprehensive Guide\", \"Building High Availability Systems with Apache ZooKeeper\", \"Mastering Rust's Unsafe Keyword: A Comprehensive Guide\", \"The Power of Immutable Data Structures in JavaScript\", \"Building a Highly Available System with Apache ZooKeeper\", \"Mastering Persistent Connections in Java\", \"Mastering Real-Time Communication with WebSockets in Elixir\", \"Understanding the Reactive Stream Pattern\", \"Understanding the Power of Rust's Macros\", \"Mastering Rust's Futures: An Advanced Guide\", \"Advanced Techniques for Working with Rust's Borrow Checker\", \"Understanding the Difference Between Block and Inline Elements in HTML\", \"Mastering Kafka Connect: A Comprehensive Guide\", \"Effective Error Handling in Swift: Best Practices and Patterns\", \"The Power of Kotlin's Coroutines: A Comprehensive Guide\", \"Mastering Asynchronous Programming in Rust: A Comprehensive Guide\", \"Building Custom Collectors in Java: A Comprehensive Guide\", \"The Art of Domain-Driven Design\", \"Exploring the Power of React's Context API: A Comprehensive Guide\", \"Mastering the Observer Pattern with Swift\", \"Mastering the Actor Model with Elixir\", \"Mastering Rust's Memory Safety Paradigm\"" | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Come up with an advanced topic for an expert level reader that is about a particular single feature, fact, pattern, paradigm, convention, theory, framework, library, or best practice." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Write a post about the chosen topic following the instructions given below:" | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Your writing style is academic, informative, and focused on detailed technical information." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "The topic should not be related to a previous post." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Use computer code snippets (in the relevant programming language) in order to illustrate the information presented." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Format the body of the post in the markdown markup language." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Come up with a title for the post and include it on the first line." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Include one to three tags for the post on the second line formatted as a comma separated list, for example: \"Tags: <tag1>, <tag2>\"." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "The post should be multiple sections in length." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Do not include links to images in the post." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Do not include contact information in the post." | ||
}, | ||
{ | ||
"role": "user", | ||
"content": "Do not add extra whitespace around lists." | ||
} | ||
], | ||
"completion": { | ||
"id": "chatcmpl-7yVNoPSUtD8cHauBtAxSiPa3l9o0k", | ||
"object": "chat.completion", | ||
"created": 1694654672, | ||
"model": "gpt-4-0613", | ||
"choices": [ | ||
{ | ||
"index": 0, | ||
"message": { | ||
"role": "assistant", | ||
"content": "# Exploring Advanced Server-Side Event Streaming with Warp in Rust\nTags: Rust, Warp, Server-Side Events\n\n## Introduction\n\nThe Warp framework is one of Rust's leading web server frameworks, allowing developers to build high-performance, safe, and concurrent web applications. One of the many features it provides is server-side event (SSE) streaming, which is a simple, effective way to push real-time updates from the server to the client over HTTP. In this post, we will deep dive into the details of server-side event streaming with Warp in Rust.\n\n## Prerequisites\n\nTo follow along with this post, you should have:\n\n- Basic understanding of Rust programming language\n- Familiarity with HTTP\n- Basic understanding of the concept of server-sent events\n\n## Warp Server and SSE Handling\n\nTo start with, let's first set up the Warp server and handle incoming requests with an SSE endpoint.\n\n```rust\nuse warp::Filter;\n\n#[tokio::main]\nasync fn main() {\n let sse_route = warp::path(\"sse\")\n .and(warp::ws())\n .map(|ws: warp::ws::Ws| {\n ws.on_upgrade(|websocket| {\n // Eliide function logic for now\n })\n });\n \n let routes = sse_route;\n\n warp::serve(routes)\n .run(([127, 0, 0, 1], 3030))\n .await;\n}\n```\n\nHere, we define an endpoint at `/sse` which upgrade the connection to WebSocket.\n\n## Handling Event Streams\n\nWarp offers a clean and convenient API for streaming server-sent events. Let's explore how we can define our server to start streaming events.\n\n```rust\nuse futures::{stream::Stream, StreamExt};\nuse std::{convert::Infallible, time::Duration};\nuse tokio::time::interval;\nuse warp::Filter;\n\nasync fn event_stream() -> Result<impl Stream<Item = Result<warp::sse::Event, warp::Error>> + Send + 'static, Infallible> {\n let mut counter: u64 = 0;\n let mut interval = interval(Duration::from_secs(1));\n\n let event_stream = async_stream::stream! {\n while let Some(_) = interval.next().await {\n counter += 1;\n\n let json_payload = serde_json::json!({\n \"counter\": counter,\n });\n\n yield Ok(warp::sse::Event::default()\n .data(serde_json::to_string(&json_payload).unwrap())\n .id(counter.to_string())\n .event(\"message\"));\n }\n };\n\n Ok(event_stream)\n}\n\n#[tokio::main]\nasync fn main() {\n let routes = warp::path(\"sse\")\n .and_then(event_stream)\n .map(|stream| {\n warp::sse::reply(warp::sse::keep_alive().stream(stream))\n });\n\n warp::serve(routes)\n .run(([127, 0, 0, 1], 3030))\n .await;\n}\n```\n\nHere, we define a function `event_stream` which returns a stream of SSE events every 1 second. Then we add it to our Warp routes, converting that stream into an HTTP response with `warp::sse::reply`.\n\n## Conclusion\n\nThe Warp framework offers an intuitive and easy-to-use framework for Rust developers to create server-sent events. With its high-performance and type-safe nature, we can ensure our SSE server handles incoming requests efficiently while preventing common runtime errors.\n\nThere's a lot more to Warp which we couldn't cover in this post, such as error handling, path parameters, request filtering, and much more. I encourage you to explore more about Warp. Feel confident in Warp's ability to handle SSEs effectively and efficiently.\n" | ||
}, | ||
"finish_reason": "stop" | ||
} | ||
], | ||
"usage": { | ||
"prompt_tokens": 2234, | ||
"completion_tokens": 780, | ||
"total_tokens": 3014 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters