int callSyncRPCDomain(const char     	   *sockfile,
					  const char 	 	   *sendbuff,
		        	  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb)
{
	static char            			dfilename[1024];
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerDomain(sockfile, 0, &fd, 0, dfilename);
	if ( res != FUNC_RETURN_OK )
	{
		elog(WARNING, "Fail to connect to domain socket server %s, result %d",
				  sockfile,
				  res);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   dfilename,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);
		elog(WARNING, "Fail to register FD for synchronous communication. %d", res);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);
	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (domain) finds exception raised.");
	}
	return res;
exit:
	closeConnectionDomain(&fd, dfilename);
	return res;
}
Ejemplo n.º 2
0
int callSyncRPCRemote(const char     	   *hostname,
					  uint16_t              port,
		  	  	  	  const char 	 	   *sendbuff,
					  int   		  		sendbuffsize,
					  uint16_t		  		sendmsgid,
					  uint16_t 		  		exprecvmsgid,
					  SelfMaintainBuffer 	recvsmb,
					  char				   *errorbuf,
					  int					errorbufsize)
{
	int 							fd 			  = -1;
	int 							res 		  = FUNC_RETURN_OK;
	AsyncCommBuffer					newcommbuffer = NULL;
	AsyncCommMessageHandlerContext 	context 	  = NULL;
	SyncRPCContextData 				userdata;

	/* Connect to the server side. */
	res = connectToServerRemote(hostname, port, &fd);
	if ( res != FUNC_RETURN_OK )
	{
		snprintf(errorbuf, errorbufsize,
				 "failed to connect to remote socket server %s:%d",
				 hostname,
				 port);
		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	initializeSyncRPContent(&userdata, recvsmb, exprecvmsgid);
	context = createMessageHandlerContext(&userdata);

	res = registerFileDesc(fd,
						   NULL,
						   ASYNCCOMM_READBYTES | ASYNCCOMM_WRITEBYTES,
						   &AsyncCommBufferHandlersMessage,
						   context,
						   &newcommbuffer);
	if ( res != FUNC_RETURN_OK )
	{
		rm_pfree(AsyncCommContext, context);

		snprintf(errorbuf, errorbufsize,
				 "failed to register socket connection fd %d connected to %s:%d "
				 "for resource rpc communication",
				 fd,
				 hostname, port);

		elog(WARNING, "%s", errorbuf);
		goto exit;
	}

	buildMessageToCommBuffer(newcommbuffer,
							 sendbuff,
							 sendbuffsize,
							 sendmsgid,
							 0,
							 0);

	context->AsyncBuffer = newcommbuffer;

	InitHandler_Message(newcommbuffer);

	/* Wait for the complete of the communication. */
	while( true )
	{
		processAllCommFileDescs();
		if ( userdata.CommStatus == SYNC_RPC_COMM_IDLE )
		{
			break;
		}
		else if ( QueryCancelPending )
		{
			/*
			 * We find that this QD wants to cancel the query, we don't need
			 * to continue the communication.
			 */
			res = TRANSCANCEL_INPROGRESS;
			break;
		}
	}

	res = res == TRANSCANCEL_INPROGRESS ? res : userdata.Result;

	/* Close and cleanup */
	closeAndRemoveAllRegisteredFileDesc();

	if (res != FUNC_RETURN_OK)
	{
	  elog(WARNING, "Sync RPC framework (inet) finds exception raised.");

	  switch(res)
	  {
	  case COMM2RM_CLIENT_FAIL_SEND:
		  snprintf(errorbuf, errorbufsize, "failed to send content");
		  break;
	  case COMM2RM_CLIENT_FAIL_RECV:
		  snprintf(errorbuf, errorbufsize, "failed to receive content");
		  break;
	  case REQUESTHANDLER_WRONGMESSAGE:
		  snprintf(errorbuf, errorbufsize, "wrong message was received");
		  break;
	  default:
		  Assert(false);
	  }
	}
	return res;
exit:
	elog(LOG, "Close fd %d at once", fd);
	closeConnectionRemote(&fd);
	return res;
}