• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Junior Year Self-Study Notes My Journey with the Hyperlane Framework

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,483
Баллы
155

Day 1: First Encounter with Hyperlane


I stumbled upon the Hyperlane Rust HTTP framework on GitHub and was immediately captivated by its performance metrics. The official documentation states:

"Hyperlane is a high-performance and lightweight Rust HTTP framework designed to simplify the development of modern web services while balancing flexibility and performance."
I decided to use it for my distributed systems course project. I started with the Cargo.toml file:


[dependencies]
hyperlane = "5.25.1"



Day 3: The Magic of Context Abstraction


Today, I delved into the design of Hyperlane's Context. In traditional frameworks, you would retrieve the request method like this:


let method = ctx.get_request().await.get_method();




But Hyperlane offers a more elegant approach:


let method = ctx.get_request_method().await;




My Understanding:

This kind of chained call simplification is akin to Rust's ? operator—it flattens nested calls and significantly enhances code readability. Hyperlane cleverly auto-generates getter/setter methods, mapping request.method to get_request_method().

Day 5: Routing and HTTP Method Macros


While attempting to implement RESTful APIs, I discovered Hyperlane's method macros:


#[methods(get, post)]
async fn user_api(ctx: Context) {
// Handle GET/POST requests
}

#[delete]
async fn delete_user(ctx: Context) {
// Handle DELETE requests
}




Encountered Issue:

At first, I forgot to add the async keyword to my route functions, which led to a half-hour of confusion due to compiler errors. Rust's asynchronous programming truly demands constant attention to detail!

Day 7: Response Handling Exploration


I spent the entire day studying the response APIs and created a comparison table to aid my understanding:

Operation TypeExample CodePurpose
Retrieve Responselet res: Response = ctx.get_response().await;Obtain the complete response object
Set Status Codectx.set_response_status_code(404).await;Set a 404 status
Send Responsectx.set_response_body("Data").send().await;Send while maintaining the connection
Close Immediatelyctx.set_response_body("Bye").send_once().await;Send and immediately close

Important Discovery:

The difference between send() and send_once() lies in the maintenance of the TCP connection, which is crucial for long-lived connections.

Day 10: Middleware Onion Model


Through the diagrams in the documentation, I understood the middleware workflow:


graph LR
A[Request] --> B[Middleware 1]
B --> C[Middleware 2]
C --> D[Controller]
D --> E[Middleware 3]
E --> F[Middleware 4]
F --> G[Response]




My Implementation:

I wrote a simple logging middleware:


async fn log_middleware(ctx: Context, next: Next) {
let start = Instant::now();
println!("-> {} {}", ctx.get_request_method().await, ctx.get_request_path().await);

next.run(ctx).await; // Call the next middleware

println!("<- {}ms", start.elapsed().as_millis());
}



Day 14: Practical Route Parameters


Today, I implemented a dynamic user interface:


// Register route
server.route("/user/{id}", user_handler).await;

// Handler function
async fn user_handler(ctx: Context) {
let user_id = ctx.get_route_param("id").await;
let user = db.find_user(user_id).await;
ctx.set_response_body_json(&user).await.send().await;
}




Pitfall Record:

When initially attempting to use a regex route like /user/{id:\d+}, I forgot to escape the backslash, leading to a compilation error. Rust's raw string literals came to the rescue:


server.route(r"/user/{id:\d+}", user_handler).await;



Day 20: Performance Test Surprise


I ran a wrk test on an AWS t2.micro instance:


wrk -c360 -d60s

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.






The results were astonishing (compared to other frameworks I learned in class):

FrameworkQPS
Hyperlane324,323
Rocket298,945
Gin (Go)242,570
Express139,412

Analysis:

Hyperlane's performance is only 5% lower than pure Tokio, yet it provides a complete web framework functionality. Rust's garbage collector-free nature combined with its asynchronous runtime is truly a powerful performance tool!

Day 25: Version Compatibility Challenge


When upgrading to v4.89+, I encountered lifecycle changes:


// Recommended way to abort a request
if should_abort {
ctx.aborted().await; // New API in v4.89+
return;
}




Lesson Learned:

It's crucial to pin version numbers in projects! The execution order of middleware can be entirely different across versions. I found this evolution diagram on GitHub:


graph TD
v3[3.0.0] -->|Middleware before routing| v4[4.0.0]
v4 -->|Separate request/response middleware| v4_22[4.22.0]
v4_22 -->|Add aborted| v4_89[4.89.0]
v4_89 -->|Add closed| v5_25[5.25.1]



Final Course Project Architecture


graph TB
A[Client] --> B[Nginx]
B --> C[Hyperlane Gateway]
C --> D[Authentication Middleware]
D --> E[Route Distribution]
E --> F[User Service]
E --> G[Order Service]
F --> H[Database]
G --> H



Learning Summary

  1. API Design Philosophy: Hyperlane's chained call design maintains Rust's elegance.
  2. Performance Secret: Built on Tokio's asynchronous architecture and zero-copy processing.
  3. Middleware System: The onion model provides clear extension points.
  4. Routing Flexibility: A balance between simple parameters and regular expressions.
  5. Version Management: Carefully read the CHANGELOG to avoid compatibility issues.

This exploration has given me a deep appreciation for Rust's potential in the web domain. Although Hyperlane is not as feature-rich as frameworks like Django, it is definitely a secret weapon in scenarios where extreme performance is required! Next, I plan to use its WebSocket capabilities to implement a real-time logging system.



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу