示例#1
0
RC TxnManager::start_commit() {
  RC rc = RCOK;
  DEBUG("%ld start_commit RO?%d\n",get_txn_id(),query->readonly());
  if(is_multi_part()) {
    if(!query->readonly() || CC_ALG == OCC || CC_ALG == MAAT) {
      // send prepare messages
      send_prepare_messages();
      rc = WAIT_REM;
    } else {
      send_finish_messages();
      rsp_cnt = 0;
      rc = commit();
    }
  } else { // is not multi-part
    rc = validate();
    if(rc == RCOK)
      rc = commit();
    else
      start_abort();
  }
  return rc;
}
void SERVER_ProcessEvent(unsigned int me, time_type now, int event_type, event_content_type *event_content, unsigned int size, state_type *state) {

	// get the server configuration from simulation state
	SERVER_lp_state_type *pointer = &state->type.server_state;
	transaction_metadata *transaction;

	switch (event_type) {

	// Configuration has just been stored
	case INIT:
		if (pointer->configuration.server_verbose) {
			printf("S%d - function Server_ProcessEvent: received SHARE_CONF\n", me);
		}
		if (me>state->num_clients+state->num_servers)
			break;
		pointer->server_id = me;
		pointer->stored_values = 0;
		pointer->last_net_iterarrival_tx_time=0;
		pointer->average_net_interarrival_tx_time=0;
		concurrency_control_init(state);
		cpu_init(pointer);

		break;

	case CPU_TX_LOCAL_GET: //return from cpu in case of local get
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received READ_LOCAL_VALUE_RET_CPU  at time %f\n", me, now);
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction == NULL) {
			printf("ERROR: no transaction found with id %d (from client id %d)\n", event_content->applicative_content.tx_id, event_content->applicative_content.client_id);
			exit(-1);
		}
		transaction->executed_operations++;
		event_content_type new_event_content;
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.object_key_id = event_content->applicative_content.object_key_id;
		new_event_content.destination_object_id = event_content->applicative_content.client_id;
		new_event_content.applicative_content.op_type = TX_GET_RETURN;
		server_send_message(state, &new_event_content, now);
		break;

	case CPU_TX_LOCAL_PUT: //return from cpu in case of local put
		if (pointer->configuration.server_verbose)
			printf("- function Server_ProcessEvent: received WRITE_VALUE_RET_CPU  at time %f\n", now);
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction == NULL) {
			printf("ERROR: no transaction found with id %d (from client id %d)\n", event_content->applicative_content.tx_id, event_content->applicative_content.client_id);
			exit(-1);
		}
		transaction->executed_operations++;
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.server_id = pointer->server_id;
		new_event_content.applicative_content.op_type = TX_PUT_RETURN;
		new_event_content.destination_object_id = event_content->applicative_content.client_id;
		server_send_message(state, &new_event_content, now);
		if (pointer->configuration.server_verbose)
			printf("- function Server_ProcessEvent: sent DELIVER_PUT_RETURN to NET at time %f\n", now);
		break;

	case CPU_TX_REMOTE_GET_RETURN: //return from cpu in case of remote get

		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: CPU_REMOTE_TX_GET_RETURN received for tx %i run number %i at time %f\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.tx_run_number, now);
		// check if a remote get response has already arrived
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction == NULL) {
			break;
		}
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.object_key_id = event_content->applicative_content.object_key_id;
		new_event_content.destination_object_id = new_event_content.applicative_content.client_id;
		new_event_content.applicative_content.op_type = TX_GET_RETURN;
		server_send_message(state, &new_event_content, now);

		break;

	case CPU_PREPARE: //return from cpu in case of prepare
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		transaction->expected_prepare_response_counter = 0;
		//stats for cubist

		//printf("\n%f",pointer->average_net_interarrival_tx_time);
		pointer->average_net_interarrival_tx_time=0.95*pointer->average_net_interarrival_tx_time+0.05*(now-pointer->last_net_iterarrival_tx_time);
		pointer->last_net_iterarrival_tx_time=now;
                
                if(transaction->write_set != NULL){
			//send prepare messages to other servers
			send_prepare_messages(state, transaction, event_content, now);
		}
		// check whether not to wait for other server response
		if (transaction->expected_prepare_response_counter == 0) {
			// can immediately commit
			if (pointer->configuration.server_verbose)
				printf("S%d - la tx %i ha solo write locali\n", me, event_content->applicative_content.tx_id);
			event_content->applicative_content.op_type = CPU_TX_DISTRIBUTED_FINAL_COMMIT;
			add_processing_request(pointer, event_content, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - CPU_DISTRIBUTED_FINAL_TX_COMMIT to cpu for transaction %i at time %f\n", me, event_content->applicative_content.tx_id, now);
		}
		break;

	case CPU_TX_LOCAL_PREPARE_SUCCESSED: //return from cpu in case of local prepare
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.op_type = TX_PREPARE_SUCCEEDED;
		new_event_content.destination_object_id = new_event_content.applicative_content.server_id;
		server_send_prepare_response_message(state, &new_event_content, now);
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: sent TX_PREPARE_SUCCEEDED for transaction %i run number %i at time %f to server %i\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.tx_run_number, now,
					new_event_content.applicative_content.server_id);
		break;

	case CPU_TX_LOCAL_PREPARE_FAILED:
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.op_type = TX_PREPARE_FAILED;
		new_event_content.destination_object_id = new_event_content.applicative_content.server_id;
		server_send_prepare_response_message(state, &new_event_content, now);
		if (pointer->configuration.server_verbose)
			printf(" S%d - function Server_ProcessEvent: sent TX_PREPARE_FAILED for transaction %i at time %f to server %i\n", me, event_content->applicative_content.tx_id, now,
					new_event_content.applicative_content.server_id);
		break;

	case CPU_TX_PREPARE_FAILED:
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received CPU_PREPARE_FAILED  for transaction %i at time %f \n", me, event_content->applicative_content.tx_id, now);
		// transaction must abort
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction != NULL && transaction->current_tx_run_number == event_content->applicative_content.tx_run_number) {

			abort_distributed_transaction(state, transaction, event_content, now);
			remove_transaction_metadata(event_content->applicative_content.tx_id, pointer);
			if (pointer->configuration.server_verbose)
				printf("S%d - function Server_ProcessEvent: transazione abortita at time %f\n", me, now);
			//reply to client
			event_content->destination_object_id = event_content->applicative_content.client_id;
			event_content->applicative_content.op_type = TX_EXECUTION_EXCEPTION;
			server_send_message(state, event_content, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - sent TX_EXECUTION_EXCEPTION for transaction %i to client %i at time %f\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.client_id,
						now);
		}
		break;

	case CPU_TX_DISTRIBUTED_FINAL_COMMIT:
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received CPU_DISTRIBUTED_FINAL_TX_COMMIT  at time %f for transaction %i\n", me, now, event_content->applicative_content.tx_id);
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if(transaction->write_set != NULL){
			commit_distributed_transaction(state, transaction, event_content, now);
		}
		remove_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		//reply to client
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.applicative_content.op_type = TX_COMMIT_RESPONSE;
		new_event_content.destination_object_id = new_event_content.applicative_content.client_id;
		server_send_message(state, &new_event_content, now);
		break;

	case CPU_TX_LOCAL_FINAL_COMMIT:
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received CPU_LOCAL_TX_FINAL_COMMIT  at time %f for transaction %i\n", me, now, event_content->applicative_content.tx_id);
		commit_remote_transaction(state, event_content, now);
		break;

	case TX_LOCAL_TIMEOUT: // timeout for a local transaction

		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received TX_LOCAL_TIMEOUT at time %f for transaction %d\n", me, now, event_content->applicative_content.tx_id);
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction != NULL && transaction->current_tx_run_number == event_content->applicative_content.tx_run_number && transaction->is_blocked) {
			event_content->applicative_content.op_type = TX_LOCAL_ABORT;
			CC_control(event_content, state, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - function Server_ProcessEvent: transaction aborted at time %f\n", me, now);
			event_content->applicative_content.op_type = CPU_TX_LOCAL_ABORT;
			remove_transaction_metadata(event_content->applicative_content.tx_id, pointer);
			add_processing_request(pointer, event_content, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - CPU_TX_LOCAL_ABORT added to CPU at time %f\n", me, now);
		}
		break;

	case TX_PREPARE_TIMEOUT: // timeout for a prepare of a remote transaction
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received TX_PREPARE_TIMEOUT at time %f for transaction %d run number %i \n", me, now, event_content->applicative_content.tx_id, event_content->applicative_content.tx_run_number);
		// remove waiting event of transaction
		transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (transaction != NULL && transaction->current_tx_run_number == event_content->applicative_content.tx_run_number && transaction->is_blocked) {
			event_content->applicative_content.op_type = TX_PREPARE_ABORT;
			CC_control(event_content, state, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - function Server_ProcessEvent: prepare of %i transaction aborted at time %f\n", me, event_content->applicative_content.tx_id, now);
			remove_transaction_metadata(event_content->applicative_content.tx_id, pointer);
			//reply to server
			memcpy(&new_event_content, event_content, sizeof(event_content_type));
			new_event_content.destination_object_id = event_content->applicative_content.server_id;
			new_event_content.applicative_content.op_type = TX_PREPARE_FAILED;
			server_send_message(state, &new_event_content, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - Server_ProcessEvent: transaction %i aborted at time %f per LOCK_TIMEOUT\n", me, event_content->applicative_content.tx_id, now);
			event_content->applicative_content.op_type = CPU_TX_REMOTE_ABORT;
			add_processing_request(pointer, event_content, now);
			if (pointer->configuration.server_verbose)
				printf("S%d - CPU_TX_REMOTE_ABORT added to CPU at time %f\n", me, now);
		}
		break;

	case CPU_TX_BEGIN: //return from cpu in case of begin
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received TX_BEGIN_RET_CPU  at time %f\n", me, now);
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.destination_object_id = event_content->applicative_content.client_id;
		new_event_content.applicative_content.op_type = TX_BEGIN_RETURN;
		server_send_message(state, &new_event_content, now);
	 	transaction = get_transaction_metadata(event_content->applicative_content.tx_id, pointer);
		if (pointer->configuration.server_verbose)
			printf("S%d - Server_ProcessEvent: TX_BEGIN_RETURN sent at time %f\n", me, now);
		break;

	case CPU_TX_LOCAL_ABORT: //return from cpu in case of local transaction abort
		if (pointer->configuration.server_verbose)
			printf("S%d - tx %i run number %i aborted at time %f\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.tx_run_number, now);
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		//reply to client
		new_event_content.destination_object_id = event_content->applicative_content.client_id;
		new_event_content.applicative_content.op_type = TX_EXECUTION_EXCEPTION;
		server_send_message(state, &new_event_content, now);
		if (pointer->configuration.server_verbose)
			printf("S%d - TX_EXECUTION_EXCEPTION of transaction %i sent to client %i at time %f\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.client_id, now);
		break;

	case CPU_TX_REMOTE_ABORT: //return from cpu in case of remote transaction abort
		abort_remote_transaction(state, event_content, now);
		break;

	case CPU_TX_LOCAL_GET_FROM_REMOTE: //return from cpu in case of local get from a remote transaction
		//send get response to the server
		if (pointer->configuration.server_verbose)
			printf("S%d - function Server_ProcessEvent: received CPU_LOCAL_TX_GET_FROM_REMOTE  at time %f\n", me, now);
		memcpy(&new_event_content, event_content, sizeof(event_content_type));
		new_event_content.destination_object_id = event_content->applicative_content.server_id;
		new_event_content.applicative_content.op_type = TX_REMOTE_GET_RETURN;
		server_send_message(state, &new_event_content, now);
		if (pointer->configuration.server_verbose)
			printf("S%d - TX_REMOTE_GET_RETURN sent to NET for tx %i run number %i at time %f\n", me, event_content->applicative_content.tx_id, event_content->applicative_content.tx_run_number,
					now);
		break;

	case CPU_TX_SEND_REMOTE_GET: //return from cpu in case of response to a remote get request
		if (pointer->configuration.server_verbose)
			printf("S%d - CPU_SEND_REMOTE_TX_GET received at time %f\n", me, now);
		send_remote_tx_get(state, event_content, now);
		break;

	case CPU_PROCESSING_REQUEST_EXECUTED: //notify a request completion to cpu
		cpu_request_executed(pointer, now);
		break;

	case DELIVER_MESSAGE: // a message from network has been received...
		process_message(me, now, event_content, state);
		break;

	default:
		printf("ERROR: event type %i not managed\n", event_type);
		exit(-1);
		break;
	}
}