Exemple #1
0
void *db_worker(void *data)
{
	int id = *((int *) data); /* Whoa... */

	struct transaction_queue_node_t *node;
	struct db_context_t *dbc;
	char code;
	double response_time;
	struct timeval rt0, rt1;
	int local_seed;
	pid_t pid;
	pthread_t tid;
	extern unsigned int seed;
	int status;

	/* Each thread needs to seed in Linux. */
    tid = pthread_self();
    pid = getpid();
	if (seed == -1) {
		struct timeval tv;
		unsigned long junk; /* Purposely used uninitialized */

		local_seed = pid;
		gettimeofday(&tv, NULL);
		local_seed ^=  tid ^ tv.tv_sec ^ tv.tv_usec ^ junk;
	} else {
		local_seed = seed;
	}
	set_random_seed(local_seed);

	/* Open a connection to the database. */
	dbc = db_init();

	if (!exiting && connect_to_db(dbc) != OK) {
		LOG_ERROR_MESSAGE("connect_to_db() error, terminating program");
		printf("cannot connect to database(see details in error.log file, exiting...\n");
		exit(1);
	}

	while (!exiting) {
		/*
		 * I know this loop will prevent the program from exiting
		 * because of the dequeue...
		 */
		node = dequeue_transaction();
		if (node == NULL) {
			LOG_ERROR_MESSAGE("dequeue was null");
			continue;
		}

		/* Execute transaction and record the response time. */
		if (gettimeofday(&rt0, NULL) == -1) {
			perror("gettimeofday");
		}

		status =
			process_transaction(node->client_data.transaction,
								dbc, &node->client_data.transaction_data);
		if (status == ERROR) {
			LOG_ERROR_MESSAGE("process_transaction() error on %s",
							  transaction_name[
								  node->client_data.transaction]);
			/*
			 * Assume this isn't a fatal error, send the results
			 * back, and try processing the next transaction.
			 */
			while (need_reconnect_to_db(dbc))
			{
				LOG_ERROR_MESSAGE("try to reconnect to database");
				disconnect_from_db(dbc);

				if (connect_to_db(dbc) != OK)
				{
					LOG_ERROR_MESSAGE("reconnect to database error, try again after sleep 5 seconds");
					sleep(5);
				}
			}
		}

		if (status == OK) {
			code = 'C';
		} else if (status == STATUS_ROLLBACK) {
			code = 'R';
		} else if (status == ERROR) {
			code = 'E';
		}

		if (gettimeofday(&rt1, NULL) == -1) {
			perror("gettimeofday");
		}

		response_time = difftimeval(rt1, rt0);
		log_transaction_mix(node->client_data.transaction, code, response_time,
							mode_altered > 0 ? node->termworker_id : node->term_id);
		enqueue_terminal(node->termworker_id, node->term_id);

		/* Keep track of how many transactions this thread has done. */
		++worker_count[id];

		/* Keep track of then the last transaction was execute. */
		time(&last_txn[id]);
	}

	/* Disconnect from the database. */
	disconnect_from_db(dbc);

	free(dbc);

	sem_wait(&db_worker_count);

	return NULL;        /* keep compiler quiet */
}
Exemple #2
0
void *db_worker(void *data)
{
        int id = *((int *) data); /* Whoa... */
#ifndef STANDALONE
        int length;
#endif /* NOT STANDALONE */
        struct transaction_queue_node_t *node;
        struct db_context_t dbc;
#ifdef STANDALONE
        struct timeval rt0, rt1;
        double response_time;
#endif /* STANDALONE */

        /* Open a connection to the database. */
#ifdef ODBC
        printf("connect to ODBC server with parameters: DSN: |%s| user: |%s| pass: |%s|\n", sname, dbt2_user, dbt2_pass);
        db_init(sname, dbt2_user, dbt2_pass);
#endif /* ODBC */
#ifdef LIBPQ
        db_init(DB_NAME, sname, postmaster_port);
#endif /* LIBPQ */

#ifdef LIBMYSQL
       printf("connect to mysql server with parameters: db_name: |%s| host: |%s| user: |%s| pass: |%s| port: |%s| socket: |%s|\n", sname, dbt2_mysql_host, dbt2_user, dbt2_pass, dbt2_mysql_port, dbt2_mysql_socket);
       db_init(sname, dbt2_mysql_host , dbt2_user, dbt2_pass, dbt2_mysql_port, dbt2_mysql_socket);
#endif /* LIBMYSQL */


        if (!exiting && connect_to_db(&dbc) != OK) {
                LOG_ERROR_MESSAGE("connect_to_db() error, terminating program");
                printf("cannot connect to database(see details in error.log file, exiting...\n");
                exit(1);
        }

        while (!exiting) {
                /*
                 * I know this loop will prevent the program from exiting
                 * because of the dequeue...
                 */
                node = dequeue_transaction();
                if (node == NULL) {
                        LOG_ERROR_MESSAGE("dequeue was null");
                        continue;
                }
#ifdef STANDALONE
                if (gettimeofday(&rt0, NULL) == -1) {
                        perror("gettimeofday");
                }
#endif /* STANDALONE */
                node->client_data.status =
                        process_transaction(node->client_data.transaction,
                        &dbc, &node->client_data.transaction_data);
                if (node->client_data.status == ERROR) {
                        LOG_ERROR_MESSAGE("process_transaction() error on %s",
                                transaction_name[
                                node->client_data.transaction]);
                        /*
                         * Assume this isn't a fatal error, send the results
                         * back, and try processing the next transaction.
                         */
                }
                else
                {
                  if (node->client_data.status == ERROR_FATAL) 
                  {
                        LOG_ERROR_MESSAGE("process_transaction() fatal error on %s",
                                transaction_name[
                                node->client_data.transaction]);
                        LOG_ERROR_MESSAGE("stopping db_thread");
                        exiting=1;
                  }
                }

#ifdef STANDALONE
                if (gettimeofday(&rt1, NULL) == -1) {
                        perror("gettimeofday");
                }
                response_time = difftimeval(rt1, rt0);
                pthread_mutex_lock(&mutex_mix_log);
                fprintf(log_mix, "%d,%c,%f,%d\n", (int) time(NULL),
                transaction_short_name[node->client_data.transaction],
                        response_time, (int) pthread_self());
                        fflush(log_mix);
                pthread_mutex_unlock(&mutex_mix_log);
#endif /* STANDALONE */

#ifndef STANDALONE
                length = send_transaction_data(node->s, &node->client_data);
                if (length == ERROR) {
                        LOG_ERROR_MESSAGE("send_transaction_data() error");
                        /*
                         * Assume this isn't a fatal error and try processing
                         * the next transaction.
                         */
                }
#endif /* NOT STANDALONE */
                pthread_mutex_lock(&mutex_transaction_counter[REQ_EXECUTING][
                        node->client_data.transaction]);
                --transaction_counter[REQ_EXECUTING][
                        node->client_data.transaction];
                pthread_mutex_unlock(&mutex_transaction_counter[REQ_EXECUTING][
                        node->client_data.transaction]);
                recycle_node(node);

                /* Keep track of how many transactions this thread has done. */
                ++worker_count[id];

                /* Keep track of then the last transaction was execute. */
                time(&last_txn[id]);
        }

        /* Disconnect from the database. */
        disconnect_from_db(&dbc);

        sem_wait(&db_worker_count);

        return NULL;        /* keep compiler quiet */
}