Skip to content

Commit

Permalink
iox-#27 Add typed API for client and server
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Feb 15, 2022
1 parent 06ec79d commit 43d6216
Show file tree
Hide file tree
Showing 6 changed files with 369 additions and 0 deletions.
63 changes: 63 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/internal/popo/client_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_CLIENT_IMPL_HPP
#define IOX_POSH_POPO_CLIENT_IMPL_HPP

#include "iceoryx_posh/capro/service_description.hpp"
#include "iceoryx_posh/internal/popo/base_client.hpp"
#include "iceoryx_posh/internal/popo/request_deleter.hpp"
#include "iceoryx_posh/internal/popo/response_deleter.hpp"
#include "iceoryx_posh/internal/popo/rpc_interface.hpp"
#include "iceoryx_posh/popo/client_options.hpp"
#include "iceoryx_posh/popo/request.hpp"
#include "iceoryx_posh/popo/response.hpp"
#include "iceoryx_posh/popo/trigger_handle.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res, typename BaseClientT = BaseClient<>>
class ClientImpl : public BaseClientT, public RpcInterface<Request<Req>>
{
public:
explicit ClientImpl(const capro::ServiceDescription& service, const ClientOptions& clientOptions = {}) noexcept;

template <typename... Args>
cxx::expected<Request<Req>, AllocationError> loan(Args&&... args) noexcept;

void send(Request<Req>&& request) noexcept override;

cxx::expected<Response<const Res>, ChunkReceiveResult> take() noexcept;

private:
using BaseClientT::port;

cxx::expected<Request<Req>, AllocationError> loanUninitialized() noexcept;

using RequestSampleDeleter = RequestDeleter<typename BaseClientT::PortType>;
RequestSampleDeleter m_requestDeleter{port()};
using ResponseSampleDeleter = ResponseDeleter<typename BaseClientT::PortType>;
ResponseSampleDeleter m_responseDeleter{port()};
};
} // namespace popo
} // namespace iox

#include "iceoryx_posh/internal/popo/client_impl.inl"

#endif // IOX_POSH_POPO_CLIENT_IMPL_HPP
83 changes: 83 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/internal/popo/client_impl.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_CLIENT_IMPL_INL
#define IOX_POSH_POPO_CLIENT_IMPL_INL

#include "iceoryx_posh/internal/popo/client_impl.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res, typename BaseClientT>
ClientImpl<Req, Res, BaseClientT>::ClientImpl(const capro::ServiceDescription& service,
const ClientOptions& clientOptions) noexcept
: BaseClientT(service, clientOptions)
{
}

template <typename Req, typename Res, typename BaseClientT>
cxx::expected<Request<Req>, AllocationError> ClientImpl<Req, Res, BaseClientT>::loanUninitialized() noexcept
{
auto result = port().allocateRequest(sizeof(Req), alignof(Req));
if (result.has_error())
{
return cxx::error<AllocationError>(result.get_error());
}
else
{
auto requestHeader = result.value();
auto payload = mepoo::ChunkHeader::fromUserHeader(requestHeader)->userPayload();
auto request = cxx::unique_ptr<Req>(reinterpret_cast<Req*>(payload), m_requestDeleter);
return cxx::success<Request<Req>>(Request<Req>{std::move(request), *this});
}
}

template <typename Req, typename Res, typename BaseClientT>
template <typename... Args>
cxx::expected<Request<Req>, AllocationError> ClientImpl<Req, Res, BaseClientT>::loan(Args&&... args) noexcept
{
return std::move(
loanUninitialized().and_then([&](auto& request) { new (request.get()) Req(std::forward<Args>(args)...); }));
}

template <typename Req, typename Res, typename BaseClientT>
void ClientImpl<Req, Res, BaseClientT>::send(Request<Req>&& request) noexcept
{
auto payload = request.release(); // release the Request ownership of the chunk before publishing
auto* requestHeader = static_cast<RequestHeader*>(mepoo::ChunkHeader::fromUserPayload(payload)->userHeader());
port().sendRequest(requestHeader);
}

template <typename Req, typename Res, typename BaseClientT>
cxx::expected<Response<const Res>, ChunkReceiveResult> ClientImpl<Req, Res, BaseClientT>::take() noexcept
{
auto result = port().getResponse();
if (result.has_error())
{
return cxx::error<ChunkReceiveResult>(result.get_error());
}
auto responseHeader = result.value();
auto payload = mepoo::ChunkHeader::fromUserHeader(responseHeader)->userPayload();
auto response = cxx::unique_ptr<const Res>(static_cast<const Res*>(payload), m_responseDeleter);
return cxx::success<Response<const Res>>(Response<const Res>{std::move(response)});
}

} // namespace popo
} // namespace iox

#endif // IOX_POSH_POPO_CLIENT_IMPL_INL
63 changes: 63 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/internal/popo/server_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_SERVER_IMPL_HPP
#define IOX_POSH_POPO_SERVER_IMPL_HPP

#include "iceoryx_posh/capro/service_description.hpp"
#include "iceoryx_posh/internal/popo/base_server.hpp"
#include "iceoryx_posh/internal/popo/request_deleter.hpp"
#include "iceoryx_posh/internal/popo/response_deleter.hpp"
#include "iceoryx_posh/internal/popo/rpc_interface.hpp"
#include "iceoryx_posh/popo/request.hpp"
#include "iceoryx_posh/popo/response.hpp"
#include "iceoryx_posh/popo/server_options.hpp"
#include "iceoryx_posh/popo/trigger_handle.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res, typename BaseServerT = BaseServer<>>
class ServerImpl : public BaseServerT, public RpcInterface<Response<Res>>
{
public:
explicit ServerImpl(const capro::ServiceDescription& service, const ServerOptions& serverOptions = {}) noexcept;

cxx::expected<Request<const Req>, ServerRequestResult> take() noexcept;

template <typename... Args>
cxx::expected<Response<Res>, AllocationError> loan(const Request<const Req>& request, Args&&... args) noexcept;

void send(Response<Res>&& response) noexcept override;

private:
using BaseServerT::port;

cxx::expected<Response<Res>, AllocationError> loanUninitialized(const Request<const Req>& request) noexcept;

using RequestSampleDeleter = RequestDeleter<typename BaseServerT::PortType>;
RequestSampleDeleter m_requestDeleter{port()};
using ResponseSampleDeleter = ResponseDeleter<typename BaseServerT::PortType>;
ResponseSampleDeleter m_responseDeleter{port()};
};
} // namespace popo
} // namespace iox

#include "iceoryx_posh/internal/popo/server_impl.inl"

#endif // IOX_POSH_POPO_SERVER_IMPL_HPP
86 changes: 86 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/internal/popo/server_impl.inl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_SERVER_IMPL_INL
#define IOX_POSH_POPO_SERVER_IMPL_INL

#include "iceoryx_posh/internal/popo/server_impl.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res, typename BaseServerT>
inline ServerImpl<Req, Res, BaseServerT>::ServerImpl(const capro::ServiceDescription& service,
const ServerOptions& serverOptions) noexcept
: BaseServerT(service, serverOptions)
{
}

template <typename Req, typename Res, typename BaseServerT>
cxx::expected<Request<const Req>, ServerRequestResult> ServerImpl<Req, Res, BaseServerT>::take() noexcept
{
auto result = port().getRequest();
if (result.has_error())
{
return cxx::error<ServerRequestResult>(result.get_error());
}
auto requestHeader = result.value();
auto payload = mepoo::ChunkHeader::fromUserHeader(requestHeader)->userPayload();
auto request = cxx::unique_ptr<const Req>(static_cast<const Req*>(payload), m_requestDeleter);
return cxx::success<Request<const Req>>(Request<const Req>{std::move(request)});
}

template <typename Req, typename Res, typename BaseServerT>
cxx::expected<Response<Res>, AllocationError>
ServerImpl<Req, Res, BaseServerT>::loanUninitialized(const Request<const Req>& request) noexcept
{
const auto* requestHeader = &request.getRequestHeader();
auto result = port().allocateResponse(requestHeader, sizeof(Req), alignof(Req));
if (result.has_error())
{
return cxx::error<AllocationError>(result.get_error());
}
else
{
auto responseHeader = result.value();
auto payload = mepoo::ChunkHeader::fromUserHeader(responseHeader)->userPayload();
auto response = cxx::unique_ptr<Res>(reinterpret_cast<Res*>(payload), m_responseDeleter);
return cxx::success<Response<Res>>(Response<Res>{std::move(response), *this});
}
}

template <typename Req, typename Res, typename BaseServerT>
template <typename... Args>
cxx::expected<Response<Res>, AllocationError> ServerImpl<Req, Res, BaseServerT>::loan(const Request<const Req>& request,
Args&&... args) noexcept
{
return std::move(loanUninitialized(request).and_then(
[&](auto& response) { new (response.get()) Res(std::forward<Args>(args)...); }));
}

template <typename Req, typename Res, typename BaseServerT>
void ServerImpl<Req, Res, BaseServerT>::send(Response<Res>&& response) noexcept
{
auto payload = response.release(); // release the Request ownership of the chunk before publishing
auto* responseHeader = static_cast<ResponseHeader*>(mepoo::ChunkHeader::fromUserPayload(payload)->userHeader());
port().sendResponse(responseHeader);
}

} // namespace popo
} // namespace iox

#endif // IOX_POSH_POPO_SERVER_IMPL_INL
39 changes: 39 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/popo/client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_CLIENT_HPP
#define IOX_POSH_POPO_CLIENT_HPP

#include "iceoryx_posh/capro/service_description.hpp"
#include "iceoryx_posh/internal/popo/client_impl.hpp"
#include "iceoryx_posh/popo/client_options.hpp"
#include "iceoryx_posh/popo/trigger_handle.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res>
class Client : public ClientImpl<Req, Res>
{
public:
using ClientImpl<Req, Res>::ClientImpl;
};
} // namespace popo
} // namespace iox

#endif // IOX_POSH_POPO_CLIENT_HPP
35 changes: 35 additions & 0 deletions iceoryx_posh/include/iceoryx_posh/popo/server.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_POSH_POPO_SERVER_HPP
#define IOX_POSH_POPO_SERVER_HPP

#include "iceoryx_posh/internal/popo/server_impl.hpp"

namespace iox
{
namespace popo
{
template <typename Req, typename Res>
class Server : public ServerImpl<Req, Res>
{
public:
using ServerImpl<Req, Res>::ServerImpl;
};
} // namespace popo
} // namespace iox

#endif // IOX_POSH_POPO_SERVER_HPP

0 comments on commit 43d6216

Please sign in to comment.