Skip to content

Commit

Permalink
Merge pull request #606 from elfenpiff/iox2-429-request-response-serv…
Browse files Browse the repository at this point in the history
…ice-builder

[#429] request response service builder
  • Loading branch information
elfenpiff authored Feb 5, 2025
2 parents 0f47a5b + 9f41339 commit 5b45d39
Show file tree
Hide file tree
Showing 36 changed files with 2,795 additions and 20 deletions.
29 changes: 29 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,32 @@ Adjusting `global` settings ensures a non-interfering setup.
Expired connection buffer size of the subscriber. Connections to publishers
are expired when the publisher disconnected from the service and the
connection contains unconsumed samples.

### Service: Request Response Messaging Pattern

* `defaults.request-response.enable-safe-overflow-for-requests` -
[`true`|`false`]: Defines if the request buffer of the service safely
overflows.
* `defaults.request-response.enable-safe-overflow-for-responses` -
[`true`|`false`]: Defines if the request buffer of the service safely
overflows.
* `defaults.request-response.max-active-responses` - [int]:
The maximum of active responses a [`crate::port::server::Server`] can hold in
parallel.
* `defaults.request-response.max-active-requests` - [int]:
The maximum of active requests a client can hold in parallel.
* `defaults.request-response.max-borrowed-responses` - [int]:
The maximum number of responses a client can borrow from an active request.
* `defaults.request-response.max-borrowed-requests` - [int]:
The maximum number of requests a server can borrow.
* `defaults.request-response.max-response-buffer-size` - [int]:
The maximum buffer size for responses for an active request.
* `defaults.request-response.max-request-buffer-size` - [int]:
The maximum buffer size for requests for a server.
* `defaults.request-response.max-servers` - [int]:
The maximum amount of supported servers.
* `defaults.request-response.max-clients` - [int]:
The maximum amount of supported clients.
* `defaults.request-response.max-nodes` - [int]:
The maximum amount of supported nodes. Defines indirectly how many
processes can open the service at the same time.
13 changes: 13 additions & 0 deletions config/iceoryx2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ connection-suffix = '.connection'
creation-timeout.secs = 0
creation-timeout.nanos = 500000000

[defaults.request-response]
enable-safe-overflow-for-requests = true
enable-safe-overflow-for-responses = true
max-active-responses = 4
max-active-requests = 2
max-borrowed-responses = 4
max-borrowed-requests = 2
max-response-buffer-size = 2
max-request-buffer-size = 4
max-servers = 2
max-clients = 8
max-nodes = 20

[defaults.publish-subscribe]
max-subscribers = 8
max-publishers = 2
Expand Down
53 changes: 53 additions & 0 deletions doc/user-documentation/request-response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Request-Response

## Classes Involved In ActiveRequest to ActiveResponse Stream Communication

User has send request to the server and receives a stream of responses.

```mermaid
classDiagram
Client "1" --> "1" DataSegment: stores request payload
Server "1" --> "1" DataSegment: stores response payload
Client "1" --> "1..*" ActiveRequest
Server "1" --> "1..*" ActiveResponse
ActiveRequest "1" --> "1" ZeroCopyConnection: receive response
ActiveResponse "1" --> "1" ZeroCopyConnection: send response
```

## Sending Request: Client View

```mermaid
sequenceDiagram
User->>+Client: loan
Client-->>-User: RequestMut
create participant RequestMut
User->>RequestMut: write_payload
destroy RequestMut
User->>+RequestMut: send
RequestMut-->>-User: ActiveRequest
create participant ActiveRequest
User->>+ActiveRequest: receive
ActiveRequest-->>-User: Response
create participant Response
User->>Response: read_payload
destroy ActiveRequest
User->>ActiveRequest: drop
```

## Responding: Server View

```mermaid
sequenceDiagram
User->>+Server: receive
Server-->>-User: ActiveResponse
create participant ActiveResponse
User->ActiveResponse: read_payload
User->>+ActiveResponse: loan
ActiveResponse-->>-User: ResponseMut
create participant ResponseMut
User->>ResponseMut: write_payload
destroy ResponseMut
User->>ResponseMut: send
destroy ActiveResponse
User->>ActiveResponse: drop
```
10 changes: 10 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ path = "rust/publish_subscribe_with_user_header/publisher.rs"
name = "publish_subscribe_user_header_subscriber"
path = "rust/publish_subscribe_with_user_header/subscriber.rs"

# request_response

[[example]]
name = "request_response_server"
path = "rust/request_response/server.rs"

[[example]]
name = "request_response_client"
path = "rust/request_response/client.rs"

# service attributes

[[example]]
Expand Down
35 changes: 35 additions & 0 deletions examples/rust/request_response/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache Software License 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
# which is available at https://opensource.org/licenses/MIT.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT

load("@rules_rust//rust:defs.bzl", "rust_binary")

rust_binary(
name = "server",
srcs = [
"server.rs",
],
deps = [
"//iceoryx2:iceoryx2",
"//examples/rust:examples-common",
],
)

rust_binary(
name = "client",
srcs = [
"client.rs",
],
deps = [
"//iceoryx2:iceoryx2",
"//examples/rust:examples-common",
],
)
1 change: 1 addition & 0 deletions examples/rust/request_response/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Request-Response
28 changes: 28 additions & 0 deletions examples/rust/request_response/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2025 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available under the
// terms of the Apache Software License 2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
// which is available at https://opensource.org/licenses/MIT.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

use examples_common::TransmissionData;
use iceoryx2::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let node = NodeBuilder::new().create::<ipc::Service>()?;

let service = node
.service_builder(&"My/Funk/ServiceName".try_into()?)
.request_response::<u64, TransmissionData>()
.open_or_create()?;

drop(service);
println!("exit");

Ok(())
}
28 changes: 28 additions & 0 deletions examples/rust/request_response/server.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2025 Contributors to the Eclipse Foundation
//
// See the NOTICE file(s) distributed with this work for additional
// information regarding copyright ownership.
//
// This program and the accompanying materials are made available under the
// terms of the Apache Software License 2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
// which is available at https://opensource.org/licenses/MIT.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

use examples_common::TransmissionData;
use iceoryx2::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let node = NodeBuilder::new().create::<ipc::Service>()?;

let service = node
.service_builder(&"My/Funk/ServiceName".try_into()?)
.request_response::<u64, TransmissionData>()
.open_or_create()?;

drop(service);
println!("exit");

Ok(())
}
4 changes: 4 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/enum_translation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ constexpr auto from<int, iox2::EventOpenOrCreateError>(const int value) noexcept
return iox2::EventOpenOrCreateError::CreateInsufficientPermissions;
case iox2_event_open_or_create_error_e_C_OLD_CONNECTION_STILL_ACTIVE:
return iox2::EventOpenOrCreateError::CreateOldConnectionsStillActive;
case iox2_event_open_or_create_error_e_SYSTEM_IN_FLUX:
return iox2::EventOpenOrCreateError::SystemInFlux;
}

IOX_UNREACHABLE();
Expand Down Expand Up @@ -585,6 +587,8 @@ constexpr auto from<int, iox2::PublishSubscribeOpenOrCreateError>(const int valu
return iox2::PublishSubscribeOpenOrCreateError::CreateHangsInCreation;
case iox2_pub_sub_open_or_create_error_e_C_OLD_CONNECTION_STILL_ACTIVE:
return iox2::PublishSubscribeOpenOrCreateError::CreateOldConnectionsStillActive;
case iox2_pub_sub_open_or_create_error_e_SYSTEM_IN_FLUX:
return iox2::PublishSubscribeOpenOrCreateError::SystemInFlux;
}

IOX_UNREACHABLE();
Expand Down
3 changes: 3 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/service_builder_event_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ enum class EventOpenOrCreateError : uint8_t {
/// [`Sample`] or
/// [`SampleMut`] in use.
CreateOldConnectionsStillActive,
/// Can occur when another process creates and removes the same [`Service`] repeatedly with a
/// high frequency.
SystemInFlux,
};

} // namespace iox2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ enum class PublishSubscribeOpenOrCreateError : uint8_t {
/// initialized. Can be caused
/// by a process that crashed during [`Service`] creation.
CreateHangsInCreation,
/// Can occur when another process creates and removes the same [`Service`] repeatedly with a
/// high frequency.
SystemInFlux,
};

} // namespace iox2
Expand Down
2 changes: 1 addition & 1 deletion iceoryx2-ffi/ffi/src/api/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub(super) struct ConfigOwner {
#[repr(C)]
#[repr(align(8))] // align_of<ConfigOwner>()
pub struct iox2_config_storage_t {
internal: [u8; 3624], // size_of<ConfigOwner>()
internal: [u8; 3704], // size_of<ConfigOwner>()
}

/// Contains the iceoryx2 config
Expand Down
2 changes: 1 addition & 1 deletion iceoryx2-ffi/ffi/src/api/service_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl ServiceBuilderUnion {
#[repr(C)]
#[repr(align(8))] // alignment of Option<ServiceBuilderUnion>
pub struct iox2_service_builder_storage_t {
internal: [u8; 464], // magic number obtained with size_of::<Option<ServiceBuilderUnion>>()
internal: [u8; 632], // magic number obtained with size_of::<Option<ServiceBuilderUnion>>()
}

#[repr(C)]
Expand Down
3 changes: 3 additions & 0 deletions iceoryx2-ffi/ffi/src/api/service_builder_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ pub enum iox2_event_open_or_create_error_e {
C_INSUFFICIENT_PERMISSIONS,
#[CStr = "old connection still active"]
C_OLD_CONNECTION_STILL_ACTIVE,
#[CStr = "same service is created and removed repeatedly"]
SYSTEM_IN_FLUX,
}

impl IntoCInt for EventOpenError {
Expand Down Expand Up @@ -172,6 +174,7 @@ impl IntoCInt for EventOpenOrCreateError {
match self {
EventOpenOrCreateError::EventOpenError(error) => error.into_c_int(),
EventOpenOrCreateError::EventCreateError(error) => error.into_c_int(),
e => e.into_c_int(),
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions iceoryx2-ffi/ffi/src/api/service_builder_pub_sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ pub enum iox2_pub_sub_open_or_create_error_e {
C_OLD_CONNECTION_STILL_ACTIVE,
#[CStr = "hangs in creation"]
C_HANGS_IN_CREATION,
#[CStr = "same service is created and removed repeatedly"]
SYSTEM_IN_FLUX,
}

impl IntoCInt for PublishSubscribeOpenError {
Expand Down Expand Up @@ -185,6 +187,7 @@ impl IntoCInt for PublishSubscribeOpenOrCreateError {
PublishSubscribeOpenOrCreateError::PublishSubscribeCreateError(error) => {
error.into_c_int()
}
e => e.into_c_int(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion iceoryx2-ffi/ffi/src/api/subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl SubscriberUnion {
#[repr(C)]
#[repr(align(16))] // alignment of Option<SubscriberUnion>
pub struct iox2_subscriber_storage_t {
internal: [u8; 816], // magic number obtained with size_of::<Option<SubscriberUnion>>()
internal: [u8; 976], // magic number obtained with size_of::<Option<SubscriberUnion>>()
}

#[repr(C)]
Expand Down
47 changes: 47 additions & 0 deletions iceoryx2/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ pub struct Defaults {
pub publish_subscribe: PublishSubscribe,
/// Default settings for the messaging pattern event
pub event: Event,
/// Default settings for the messaging pattern request-response
pub request_response: RequestResonse,
}

/// Default settings for the publish-subscribe messaging pattern. These settings are used unless
Expand Down Expand Up @@ -300,6 +302,38 @@ pub struct Event {
pub notifier_dead_event: Option<usize>,
}

/// Default settings for the request response messaging pattern. These settings are used unless
/// the user specifies custom QoS or port settings.
#[non_exhaustive]
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub struct RequestResonse {
/// Defines if the request buffer of the [`Service`] safely overflows.
pub enable_safe_overflow_for_requests: bool,
/// Defines if the response buffer of the [`Service`] safely overflows.
pub enable_safe_overflow_for_responses: bool,
/// The maximum of active responses a [`crate::port::server::Server`] can hold in parallel.
pub max_active_responses: usize,
/// The maximum of active requests a [`crate::port::client::Client`] can hold in parallel.
pub max_active_requests: usize,
/// The maximum number of responses a [`crate::port::client::Client`] can borrow from
/// an active request.
pub max_borrowed_responses: usize,
/// The maximum number of requests a [`crate::port::server::Server`] can borrow.
pub max_borrowed_requests: usize,
/// The maximum buffer size for responses for an active request.
pub max_response_buffer_size: usize,
/// The maximum buffer size for requests for a [`crate::port::server::Server`].
pub max_request_buffer_size: usize,
/// The maximum amount of supported [`crate::port::server::Server`]
pub max_servers: usize,
/// The maximum amount of supported [`crate::port::client::Client`]
pub max_clients: usize,
/// The maximum amount of supported [`crate::node::Node`]s. Defines indirectly how many
/// processes can open the service at the same time.
pub max_nodes: usize,
}

/// Represents the configuration that iceoryx2 will utilize. It is divided into two sections:
/// the [Global] settings, which must align with the iceoryx2 instance the application intends to
/// join, and the [Defaults] for communication within that iceoryx2 instance. The user has the
Expand Down Expand Up @@ -342,6 +376,19 @@ impl Default for Config {
},
},
defaults: Defaults {
request_response: RequestResonse {
enable_safe_overflow_for_requests: true,
enable_safe_overflow_for_responses: true,
max_active_responses: 4,
max_active_requests: 2,
max_borrowed_responses: 4,
max_borrowed_requests: 2,
max_response_buffer_size: 2,
max_request_buffer_size: 4,
max_servers: 2,
max_clients: 8,
max_nodes: 20,
},
publish_subscribe: PublishSubscribe {
max_subscribers: 8,
max_publishers: 2,
Expand Down
Loading

0 comments on commit 5b45d39

Please sign in to comment.