Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

daemon: Generate transfer_id on server side #1517

Merged
merged 1 commit into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
<method name="list_fd">
<arg name="options" type="a{sv}" direction="in"/>
<arg name="file_descriptor" type="h" direction="in"/>
<arg name="transfer_id" type="s" direction="in"/>
<arg name="transfer_id" type="s" direction="out"/>
</method>

<!--
Expand Down
15 changes: 6 additions & 9 deletions dnf5daemon-server/services/rpm/rpm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ void Rpm::dbus_register() {
dbus_object->registerMethod(
dnfdaemon::INTERFACE_RPM,
"list_fd",
"a{sv}hs",
{"options", "file_descriptor", "transfer_id"},
"",
{},
"a{sv}h",
{"options", "file_descriptor"},
"s",
{"transfer_id"},
[this](sdbus::MethodCall call) -> void {
session.get_threads_manager().handle_method_fd(*this, &Rpm::list_fd, call, session.session_locale);
});
Expand Down Expand Up @@ -418,16 +418,13 @@ sdbus::MethodReply Rpm::list(sdbus::MethodCall & call) {
return reply;
}

void Rpm::list_fd(sdbus::MethodCall & call) {
void Rpm::list_fd(sdbus::MethodCall & call, const std::string & transfer_id) {
// read options from dbus call
dnfdaemon::KeyValueMap options;
call >> options;
// get the output pipe file descriptor
sdbus::UnixFd dbus_unix_fd;
call >> dbus_unix_fd;
// id of the output filedescriptor
std::string out_fd_id;
call >> out_fd_id;

int out_fd = dbus_unix_fd.get();

Expand Down Expand Up @@ -462,7 +459,7 @@ void Rpm::list_fd(sdbus::MethodCall & call) {
auto dbus_object = get_session().get_dbus_object();
auto signal = dbus_object->createSignal(call.getInterfaceName(), dnfdaemon::SIGNAL_WRITE_TO_FD_FINISHED);
signal << error_msg.empty();
signal << out_fd_id;
signal << transfer_id;
signal << error_msg;
try {
dbus_object->emitSignal(signal);
Expand Down
2 changes: 1 addition & 1 deletion dnf5daemon-server/services/rpm/rpm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Rpm : public IDbusSessionService {
sdbus::MethodReply downgrade(sdbus::MethodCall & call);
sdbus::MethodReply reinstall(sdbus::MethodCall & call);

void list_fd(sdbus::MethodCall & call);
void list_fd(sdbus::MethodCall & call, const std::string & transfer_id);
};

#endif
13 changes: 9 additions & 4 deletions dnf5daemon-server/threads_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,27 @@ class ThreadsManager {
template <class S>
void handle_method_fd(
S & service,
void (S::*method)(sdbus::MethodCall &),
void (S::*method)(sdbus::MethodCall &, const std::string &),
sdbus::MethodCall & call,
std::optional<std::string> thread_locale = std::nullopt) {
auto worker = std::thread(
[this](
S & service,
void (S::*method)(sdbus::MethodCall &),
void (S::*method)(sdbus::MethodCall &, const std::string &),
sdbus::MethodCall call,
std::optional<std::string> thread_locale = std::nullopt) {
static unsigned int counter{0};
locale_t new_locale{nullptr};
locale_t orig_locale{nullptr};
if (thread_locale) {
orig_locale = set_thread_locale(thread_locale.value(), new_locale);
}

const sdbus::MethodReply reply = call.createReply();
sdbus::MethodReply reply = call.createReply();
// generate unique transfer id based on client bus name and counter
const std::string transfer_id = fmt::format("{}-{}", call.getSender(), ++counter);
reply << transfer_id;

std::string error_msg;
try {
reply.send();
Expand All @@ -135,7 +140,7 @@ class ThreadsManager {

if (error_msg.empty()) {
try {
(service.*method)(call);
(service.*method)(call, transfer_id);
} catch (...) {
// TODO(mblaha): log the error
}
Expand Down
7 changes: 5 additions & 2 deletions doc/dnf_daemon/examples/rpm_list_fd.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def repoquery(iface_rpm, options):
pipe_r, pipe_w = os.pipe()
# transfer id serves as an identifier of the pipe transfer for a signal emitted
# after server finish. This example does not use it.
iface_rpm.list_fd(options, pipe_w, "the_transfer_id")
transfer_id = iface_rpm.list_fd(options, pipe_w)
print("transfer_id: ", transfer_id)
# close the write end - otherwise poll cannot detect the end of transmission
os.close(pipe_w)

Expand Down Expand Up @@ -89,6 +90,8 @@ def repoquery(iface_rpm, options):
try:
# skip all chars till begin of next JSON objects (new lines mostly)
json_obj_start = to_parse.find('{')
if json_obj_start < 0:
break
obj, end = parser.raw_decode(to_parse[json_obj_start:])
yield obj
to_parse = to_parse[(json_obj_start+end):]
Expand All @@ -108,7 +111,7 @@ def repoquery(iface_rpm, options):

# non-empty to_parse here means there are some unfinished (or generally unparsable)
# JSON objects in the stream.
if to_parse:
if to_parse.strip():
raise Exception("Failed to parse part of received data.")


Expand Down
Loading