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 tobodyWriterwhen 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.