On Tue, 06 Sep 2016 12:29:13 GMT, Jack Applegame wrote:
You said
It was a bad idea because when this function running, you can't write to response bodyWriter.
But how you can write tobodyWriter
when runningwaitForConnectionClose()
without creating parallel task and sharing connection between them?
However, I believe thatwaitForConnectionClose()
should not take ownership.Could you post your previous problematic code, please.
This is part of web interface:
void getChanneldown(HTTPServerRequest request, HTTPServerResponse response)
{
import ChannelD;
auto controller = getController(request);
scope channel = new ChannelD;
channel.setExitByHTTPClose(response);
controller.subscribe(channel.writer);
scope(exit) controller.unsubscribe();
channel.run(response.bodyWriter);
}
This is method ChannelD.run:
/**
* Run download channel
*/
void run(OutputStream response)
{
// running flag
running = true;
scope(exit) running = false;
// output with flush
void echo(string message)
{
response.write(message);
response.flush;
}
// send all messages to client
void sendAll()
{
debug
{
import std.stdio: writeln;
writeln("send to stream:", messagesToSend.serializeToJson.toString);
}
echo(messagesToSend.serializeToJson.toString);
}
// if mesages exists, just send it end exit
if(messagesToSend.length)
{
sendAll();
return;
}
// waiting loop will be in this task
writer = Task.getThis();
// forced drop connection after interval
if(channel_reload_interval.total!"seconds" > 0)
runTask((){
sleep(channel_reload_interval);
if(stillRunning)
writer.send(WriterCommand.FlushAndExit);
});
// run pinger to keep connection alive
auto pinger = runTask((){
while(stillRunning){
writer.send(WriterCommand.Ping);
sleep(ping_interval);
}
});
// run main writer
bool exit = false;
while(!exit) receive(
(WriterCommand cmd){
with(WriterCommand) final switch(cmd)
{
case Ping:
echo(" ");
break;
case FlushAndExit:
sendAll();
goto case;
case JustExit:
exit = true;
break;
}
},
(ChannelMessage message){
messagesToSend ~= message;
sendAll();
exit = true;
}
);
response.finalize();
}
}
And now setExitByHTTPClose():
void setExitByHTTPClose(HTTPServerResponse response)
{
runTask((){
while(response.connected())
sleep(5.seconds);
if(stillRunning)
writer.send(WriterCommand.JustExit);
});
}
There delegate in another Task uses response object. Now there is not error.
before if was like
runTask((){
while(!response.waitForConnectionClose()){}
if(stillRunning)
writer.send(WriterCommand.JustExit);
});
and it was error described in my first message.