-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
42 changed files
with
556 additions
and
846 deletions.
There are no files selected for viewing
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
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
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
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,74 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#include "runtime-light/stdlib/component/component-api.h" | ||
|
||
#include <cstdint> | ||
|
||
#include "runtime-core/runtime-core.h" | ||
#include "runtime-core/utils/kphp-assert-core.h" | ||
#include "runtime-light/component/component.h" | ||
#include "runtime-light/coroutine/awaitable.h" | ||
#include "runtime-light/coroutine/task.h" | ||
#include "runtime-light/streams/streams.h" | ||
#include "runtime-light/utils/context.h" | ||
|
||
// === component query client interface =========================================================== | ||
|
||
task_t<class_instance<C$ComponentQuery>> f$component_client_send_request(string name, string message) noexcept { | ||
const auto stream_d{get_component_context()->open_stream(name)}; | ||
if (stream_d == INVALID_PLATFORM_DESCRIPTOR) { | ||
co_return class_instance<C$ComponentQuery>{}; | ||
} | ||
|
||
int32_t written{co_await write_all_to_stream(stream_d, message.c_str(), message.size())}; | ||
if (written != message.size()) { | ||
php_warning("can't send request to component '%s'", name.c_str()); | ||
co_return class_instance<C$ComponentQuery>{}; | ||
} | ||
|
||
get_platform_context()->shutdown_write(stream_d); | ||
php_debug("sent %d bytes from %d to '%s' on stream %" PRIu64, written, message.size(), name.c_str(), stream_d); | ||
co_return make_instance<C$ComponentQuery>(stream_d); | ||
} | ||
|
||
task_t<string> f$component_client_fetch_response(class_instance<C$ComponentQuery> query) noexcept { | ||
uint64_t stream_d{query.is_null() ? INVALID_PLATFORM_DESCRIPTOR : query.get()->stream_d}; | ||
if (stream_d == INVALID_PLATFORM_DESCRIPTOR) { | ||
php_warning("can't fetch component response from stream %" PRIu64, stream_d); | ||
co_return string{}; | ||
} | ||
|
||
const auto [buffer, size]{co_await read_all_from_stream(stream_d)}; | ||
string result{buffer, static_cast<string::size_type>(size)}; | ||
get_platform_context()->allocator.free(buffer); | ||
php_debug("read %d bytes from stream %" PRIu64, size, stream_d); | ||
get_component_context()->release_stream(stream_d); | ||
query.get()->stream_d = INVALID_PLATFORM_DESCRIPTOR; | ||
co_return result; | ||
} | ||
|
||
// === component query server interface =========================================================== | ||
|
||
task_t<class_instance<C$ComponentQuery>> f$component_server_accept_query() noexcept { | ||
co_return make_instance<C$ComponentQuery>(co_await wait_for_incoming_stream_t{}); | ||
} | ||
|
||
task_t<string> f$component_server_fetch_request(class_instance<C$ComponentQuery> query) noexcept { | ||
uint64_t stream_d{query.is_null() ? INVALID_PLATFORM_DESCRIPTOR : query.get()->stream_d}; | ||
const auto [buffer, size]{co_await read_all_from_stream(stream_d)}; | ||
string result{buffer, static_cast<string::size_type>(size)}; | ||
get_platform_context()->allocator.free(buffer); | ||
co_return result; | ||
} | ||
|
||
task_t<void> f$component_server_send_response(class_instance<C$ComponentQuery> query, string message) noexcept { | ||
uint64_t stream_d{query.is_null() ? INVALID_PLATFORM_DESCRIPTOR : query.get()->stream_d}; | ||
if ((co_await write_all_to_stream(stream_d, message.c_str(), message.size())) != message.size()) { | ||
php_warning("can't send component response to stream %" PRIu64, stream_d); | ||
} else { | ||
php_debug("sent %d bytes as response to stream %" PRIu64, message.size(), stream_d); | ||
} | ||
get_component_context()->release_stream(stream_d); | ||
} |
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,59 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
#include <string_view> | ||
#include <utility> | ||
|
||
#include "runtime-core/class-instance/refcountable-php-classes.h" | ||
#include "runtime-core/runtime-core.h" | ||
#include "runtime-light/component/component.h" | ||
#include "runtime-light/coroutine/task.h" | ||
#include "runtime-light/utils/context.h" | ||
|
||
// === ComponentQuery ============================================================================= | ||
|
||
struct C$ComponentQuery final : public refcountable_php_classes<C$ComponentQuery> { | ||
uint64_t stream_d{INVALID_PLATFORM_DESCRIPTOR}; | ||
|
||
explicit constexpr C$ComponentQuery(uint64_t stream_d_) noexcept | ||
: stream_d(stream_d_) {} | ||
constexpr C$ComponentQuery(C$ComponentQuery &&other) noexcept | ||
: stream_d(std::exchange(other.stream_d, INVALID_PLATFORM_DESCRIPTOR)) {}; | ||
|
||
C$ComponentQuery(const C$ComponentQuery &) = delete; | ||
C$ComponentQuery &operator=(const C$ComponentQuery &) = delete; | ||
C$ComponentQuery &operator=(C$ComponentQuery &&other) = delete; | ||
|
||
constexpr const char *get_class() const noexcept { | ||
return "ComponentQuery"; | ||
} | ||
|
||
constexpr int32_t get_hash() const noexcept { | ||
return static_cast<int32_t>(std::hash<std::string_view>{}(get_class())); | ||
} | ||
|
||
~C$ComponentQuery() { | ||
auto &component_ctx{*get_component_context()}; | ||
if (component_ctx.opened_streams().contains(stream_d)) { | ||
component_ctx.release_stream(stream_d); | ||
} | ||
} | ||
}; | ||
|
||
// === component query client interface =========================================================== | ||
|
||
task_t<class_instance<C$ComponentQuery>> f$component_client_send_request(string name, string message) noexcept; | ||
|
||
task_t<string> f$component_client_fetch_response(class_instance<C$ComponentQuery> query) noexcept; | ||
|
||
// === component query server interface =========================================================== | ||
|
||
task_t<class_instance<C$ComponentQuery>> f$component_server_accept_query() noexcept; | ||
|
||
task_t<string> f$component_server_fetch_request(class_instance<C$ComponentQuery> query) noexcept; | ||
|
||
task_t<void> f$component_server_send_response(class_instance<C$ComponentQuery> query, string message) noexcept; |
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,65 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2024 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#include "runtime-light/stdlib/exit/exit-functions.h" | ||
|
||
#include <cstdint> | ||
|
||
#include "runtime-core/utils/kphp-assert-core.h" | ||
#include "runtime-light/component/component.h" | ||
#include "runtime-light/header.h" | ||
#include "runtime-light/streams/streams.h" | ||
#include "runtime-light/utils/context.h" | ||
|
||
namespace { | ||
|
||
int32_t ob_merge_buffers() noexcept { | ||
Response &response{get_component_context()->response}; | ||
php_assert(response.current_buffer >= 0); | ||
|
||
int32_t ob_first_not_empty{}; | ||
while (ob_first_not_empty < response.current_buffer && response.output_buffers[ob_first_not_empty].size() == 0) { | ||
++ob_first_not_empty; | ||
} | ||
for (auto i = ob_first_not_empty + 1; i <= response.current_buffer; i++) { | ||
response.output_buffers[ob_first_not_empty].append(response.output_buffers[i].c_str(), response.output_buffers[i].size()); | ||
} | ||
return ob_first_not_empty; | ||
} | ||
|
||
} // namespace | ||
|
||
task_t<void> shutdown_script() noexcept { | ||
auto &component_ctx{*get_component_context()}; | ||
const auto standard_stream{component_ctx.standard_stream()}; | ||
if (standard_stream == INVALID_PLATFORM_DESCRIPTOR) { | ||
component_ctx.poll_status = PollStatus::PollFinishedError; | ||
co_return; | ||
} | ||
|
||
const auto &buffer{component_ctx.response.output_buffers[ob_merge_buffers()]}; | ||
if ((co_await write_all_to_stream(standard_stream, buffer.buffer(), buffer.size())) != buffer.size()) { | ||
php_warning("can't write component result to stream %" PRIu64, standard_stream); | ||
} | ||
} | ||
|
||
task_t<void> f$exit(const mixed &v) noexcept { // TODO: make it synchronous | ||
int64_t exit_code{}; | ||
if (v.is_string()) { | ||
Response &response{get_component_context()->response}; | ||
response.output_buffers[response.current_buffer] << v; | ||
} else if (v.is_int()) { | ||
int64_t v_code{v.to_int()}; | ||
// valid PHP exit codes: [0..254] | ||
exit_code = v_code >= 0 && v_code <= 254 ? v_code : 1; | ||
} else { | ||
exit_code = 1; | ||
} | ||
co_await shutdown_script(); | ||
auto &component_ctx{*get_component_context()}; | ||
component_ctx.poll_status = | ||
component_ctx.poll_status != PollStatus::PollFinishedError && exit_code == 0 ? PollStatus::PollFinishedOk : PollStatus::PollFinishedError; | ||
component_ctx.release_all_streams(); | ||
get_platform_context()->abort(); | ||
} |
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
This file was deleted.
Oops, something went wrong.
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
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.