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;
}
int MainHandlerLoop_RMSEG(void)
{
	int 		res 	  = FUNC_RETURN_OK;
	uint64_t    curtime   = 0;
	int			errorcode = FUNC_RETURN_OK;
	char		errorbuf[1024];

	while( DRMGlobalInstance->ResManagerMainKeepRun ) {

		if (!PostmasterIsAlive(true)) {
			DRMGlobalInstance->ResManagerMainKeepRun = false;
			elog(LOG, "Postmaster is not alive, resource manager exits");
			break;
		}

		/* PART1. Handle socket server inputs. */
		res = processAllCommFileDescs();
		if ( res != FUNC_RETURN_OK ) {
			/*
			 * The possible error here is the failure of poll(), we won't keep
			 * running HAWQ RM any longer, graceful quit is requested.
			 */
			DRMGlobalInstance->ResManagerMainKeepRun = false;
			elog(LOG, "System error cause resource manager not possible to track "
					  "network communications.");
		}

		/* PART2. Handle all BE submitted requests. */
		processSubmittedRequests();

		/* PART3. Fresh local host info and send IMAlive message to resource
		 * 		  manager server.											  */
		curtime = gettime_microsec();
		if ( DRMGlobalInstance->LocalHostStat == NULL ||
			 curtime - DRMGlobalInstance->LocalHostLastUpdateTime >
			 SEGMENT_HOSTCHECK_INTERVAL ) {
			refreshLocalHostInstance();
			checkLocalPostmasterStatus();
		}

		if ( DRMGlobalInstance->SendIMAlive ) {
			 if (DRMGlobalInstance->LocalHostStat != NULL &&
			     curtime - DRMGlobalInstance->HeartBeatLastSentTime >
			     SEGMENT_HEARTBEAT_INTERVAL ) {
				 sendIMAlive(&errorcode, errorbuf, sizeof(errorbuf));
				 DRMGlobalInstance->HeartBeatLastSentTime = gettime_microsec();
			 }
		}

		/* PART4. Send responses back to the clients. */
		sendResponseToClients();

		/* PART5. Resource enforcement work thread quit */
		if (g_enforcement_thread_quited) {
			elog(ERROR, "Resource enforcement thread quited");
		}
	}

	elog(RMLOG, "Resource manager main event handler exits.");

	return res;
}
예제 #3
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;
}