0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-28 14:58:20 +02:00

ircd:Ⓜ️:app: Improve stdout handler; member state off of worker stack.

This commit is contained in:
Jason Volk 2020-10-28 00:42:32 -07:00
parent 8f5b4704be
commit 55e7b83ca7
2 changed files with 81 additions and 74 deletions

View file

@ -28,9 +28,14 @@ struct ircd::m::app
json::array arg;
std::string binpath;
std::vector<json::string> argv;
unique_mutable_buffer outbuf;
exec child;
id::user::buf user_id;
id::room::buf room_id;
id::event::buf event_id;
context worker_context;
bool handle_stdout();
void worker();
app(const m::event::idx &);

View file

@ -228,10 +228,26 @@ ircd::m::app::app(const m::event::idx &event_idx)
ret.at(0) = binpath;
return ret;
}()}
,outbuf
{
32_KiB
}
,child
{
argv
}
,user_id
{
m::get(event_idx, "sender")
}
,room_id
{
m::room_id(event_idx)
}
,event_id
{
m::event_id(event_idx)
}
,worker_context
{
"m.app",
@ -251,21 +267,6 @@ void
ircd::m::app::worker()
try
{
const auto event_id
{
m::event_id(event_idx)
};
const auto room_id
{
m::room_id(event_idx)
};
const auto user_id
{
m::get(event_idx, "sender")
};
child.dock.wait([this]
{
return child.pid >= 0;
@ -283,67 +284,12 @@ try
child.pid,
};
char buf alignas(4096) [16_KiB];
for(run::barrier<ctx::interrupted>{};;)
run::barrier<ctx::interrupted>{}; do
{
window_buffer wb(buf);
wb([](const mutable_buffer &buf)
{
return copy(buf, "<pre>"_sv);
});
bool eof {false};
wb([this, &eof](const mutable_buffer &buf)
{
const auto ret(read(this->child, buf));
eof = empty(ret);
return ret;
});
wb([](const mutable_buffer &buf)
{
return copy(buf, "</pre>"_sv);
});
const string_view &output
{
wb.completed()
};
if(eof)
{
log::debug
{
log, "app:%lu :end of file",
event_idx,
};
return;
}
const string_view alt
{
"no alt text"
};
const auto message_id
{
!ircd::write_avoid?
m::msghtml(room_id, user_id, output, alt, "m.notice"):
m::event::id::buf{}
};
log::debug
{
log, "app:%lu output %zu bytes in %s to %s :%s%s",
event_idx,
size(output),
string_view{message_id},
string_view{room_id},
trunc(output, 64),
size(output) > 64? "...": "",
};
if(!handle_stdout())
break;
}
while(1);
}
catch(const std::exception &e)
{
@ -359,3 +305,59 @@ catch(const std::exception &e)
child.join();
return;
}
bool
ircd::m::app::handle_stdout()
{
mutable_buffer buf(this->outbuf);
consume(buf, copy(buf, "<pre>"_sv));
const string_view output
{
read(this->child, buf)
};
consume(buf, size(output));
if(empty(output))
{
log::debug
{
log, "app:%lu :end of file",
this->event_idx,
};
return false;
}
consume(buf, copy(buf, "</pre>"_sv));
const string_view &content
{
data(this->outbuf), data(buf)
};
const fmt::bsprintf<96> alt
{
"app:%lu wrote %zu bytes to stdout.",
this->event_idx,
size(output),
};
const auto message_id
{
!ircd::write_avoid?
m::msghtml(room_id, user_id, content, string_view{alt}, "m.notice"):
m::event::id::buf{}
};
log::debug
{
log, "app:%lu output %zu bytes in %s to %s :%s%s",
event_idx,
size(content),
string_view{message_id},
string_view{room_id},
trunc(content, 64),
size(content) > 64? "...": "",
};
return true;
}