RejectedSoftware Forums

Sign up

Task terminated with unhandled exception: Acquiring reader of already owned connection.

Hi all!
How to deal with such type of error? No my code in trace, no clue what happened and where to see.

Task terminated with unhandled exception: Acquiring reader of already owned connection.
core.exception.AssertError@../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/drivers/libevent2_tcp.d(419): Acquiring reader of already owned connection.
----------------
??:? _d_assert_msg [0x914651]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/drivers/libevent2_tcp.d:419 void vibe.core.drivers.libevent2_tcp.Libevent2TCPConnection.checkReader() [0x875c5f]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/drivers/libevent2_tcp.d:227 @property bool vibe.core.drivers.libevent2_tcp.Libevent2TCPConnection.dataAvailableForRead() [0x874e5e]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/drivers/libevent2_tcp.d:306 bool vibe.core.drivers.libevent2_tcp.Libevent2TCPConnection.waitForData(core.time.Duration) [0x8753c0]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/http/server.d:1557 void vibe.http.server.handleHTTPConnection(vibe.core.net.TCPConnection, vibe.http.server.HTTPListenInfo) [0x823e8a]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/http/server.d:1433 void vibe.http.server.listenHTTPPlain(vibe.http.server.HTTPServerSettings).doListen(vibe.http.server.HTTPListenInfo, bool, bool).__lambda4(vibe.core.net.TCPConnection) [0x823810]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/drivers/libevent2_tcp.d:610 void vibe.core.drivers.libevent2_tcp.ClientTask.execute() [0x8da8b1]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/core.d:488 void vibe.core.core.makeTaskFuncInfo!(void delegate()).makeTaskFuncInfo(ref void delegate()).callDelegate(vibe.core.core.TaskFuncInfo*) [0x75ed21]
../../.dub/packages/vibe-d-0.7.29/vibe-d/source/vibe/core/core.d:1119 void vibe.core.core.CoreTask.run() [0x868715]
??:? void core.thread.Fiber.run() [0x96af65]
??:? fiber_entryPoint [0x96ace7]
??:? [0xffffffff]

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

On Sun, 04 Sep 2016 16:45:43 GMT, Alexey Kulentsov wrote:

Hi all!
How to deal with such type of error? No my code in trace, no clue what happened and where to see.

Task terminated with unhandled exception: Acquiring reader of already owned connection.

Ok, I resolve it, but it was not good time.
http://vibed.org/api/vibe.http.server/HTTPServerResponse.waitForConnectionClose
I tried to use this function to close my service threads on HTTP connection close. It was a bad idea because when this function running, you can't write to response bodyWriter. I found in documentation nothing about this exclusive usage.

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

On Tue, 06 Sep 2016 00:28:57 GMT, Alexey Kulentsov wrote:

On Sun, 04 Sep 2016 16:45:43 GMT, Alexey Kulentsov wrote:
Ok, I resolve it, but it was not good time.
http://vibed.org/api/vibe.http.server/HTTPServerResponse.waitForConnectionClose
I tried to use this function to close my service threads on HTTP connection close. It was a bad idea because when this function running, you can't write to response bodyWriter. I found in documentation nothing about this exclusive usage.

I'm pretty sure that sharing the connection between the tasks is impossible.

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

On Tue, 06 Sep 2016 06:42:23 GMT, Jack Applegame wrote:

On Tue, 06 Sep 2016 00:28:57 GMT, Alexey Kulentsov wrote:

On Sun, 04 Sep 2016 16:45:43 GMT, Alexey Kulentsov wrote:
Ok, I resolve it, but it was not good time.
http://vibed.org/api/vibe.http.server/HTTPServerResponse.waitForConnectionClose
I tried to use this function to close my service threads on HTTP connection close. It was a bad idea because when this function running, you can't write to response bodyWriter. I found in documentation nothing about this exclusive usage.
I'm pretty sure that sharing the connection between the tasks is impossible.

It's not about sharing connection, because when I replace waitForConnectionClose() for explicit waiting loop then problem disappears. Now this method looks like:

void setExitByHTTPClose(HTTPServerResponse response)
{
	runTask((){
			while(response.connected())
				sleep(5.seconds);
			if(stillRunning)
				writer.send(WriterCommand.JustExit);
	});
}


Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

On Tue, 06 Sep 2016 11:53:11 GMT, Alexey Kulentsov wrote:

It's not about sharing connection, because when I replace waitForConnectionClose() for explicit waiting loop then problem disappears. Now this method looks like:

void setExitByHTTPClose(HTTPServerResponse response)
{
	runTask((){
			while(response.connected())
				sleep(5.seconds);
			if(stillRunning)
				writer.send(WriterCommand.JustExit);
	});
}


You said

It was a bad idea because when this function running, you can't write to response bodyWriter.

But how you can write to bodyWriter when running waitForConnectionClose() without creating parallel task and sharing connection between them?
However, I believe that waitForConnectionClose() should not take ownership.

Could you post your previous problematic code, please.

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

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 to bodyWriter when running waitForConnectionClose() without creating parallel task and sharing connection between them?
However, I believe that waitForConnectionClose() 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.

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

I don't see anything wrong. You start three tasks: pinger, closed connection watcher and channel worker. But only one task (channel worker) sends data to the stream.
Looks like a bug.

Re: Task terminated with unhandled exception: Acquiring reader of already owned connection.

On Wed, 07 Sep 2016 06:50:04 GMT, Jack Applegame wrote:

I don't see anything wrong. You start three tasks: pinger, closed connection watcher and channel worker. But only one task (channel worker) sends data to the stream.
Looks like a bug.

I made repo with minimal code to experiment:

git clone https://github.com/crimaniak/waitForConn.git

I hope Sönke will explain what is wrong here.