Exemple #1
0
static int connect(lua_State *L){
	const char *hostName = luaL_checkstring(L, 1);
	int port = lua_tointeger(L, 2);
	as_error err;

	// Configuration for the client.
	as_config config;
	as_config_init(&config);

	// Add a seed host for cluster discovery.
	config.hosts[0].addr = hostName;
	config.hosts[0].port = port;

	// The Aerospike client instance, initialized with the configuration.
	aerospike as;
	aerospike_init(&as, &config);

	// Connect to the cluster.
	aerospike_connect(&as, &err);

	/* Push the return */
	lua_pushnumber(L, err.code);
	lua_pushstring(L, err.message);
	lua_pushlightuserdata(L, &as);
	return 3;
}
//------------------------------------------------
// Connect to database cluster, setting UDF
// configuration.
//
void
example_connect_to_aerospike_with_udf_config(aerospike* p_as,
		const char* lua_user_path)
{
	// Start with default configuration.
	as_config cfg;
	as_config_init(&cfg);

	// Must provide host and port. Example must have called example_get_opts()!
	cfg.hosts[0].addr = g_host;
	cfg.hosts[0].port = g_port;

	// Explicitly set Lua system path if it's not the default installation path
	// '/opt/aerospike/sys/udf/lua'
//	strcpy(cfg.lua.system_path, "/home/citrusleaf/aerospike-client-c/aerospike-mod-lua/src/lua");

	if (lua_user_path) {
		strcpy(cfg.lua.user_path, lua_user_path);
	}

	as_error err;

	// Connect to the Aerospike database cluster. Assume this is the first thing
	// done after calling example_get_opts(), so it's ok to exit on failure.
	if (aerospike_connect(aerospike_init(p_as, &cfg), &err) != AEROSPIKE_OK) {
		LOG("aerospike_connect() returned %d - %s", err.code, err.message);
		aerospike_destroy(p_as);
		exit(-1);
	}
}
static aerospike*
aerospike_defaults(aerospike* as, bool free, as_config* config)
{
	as->_free = free;
	as->cluster = NULL;
	if ( config != NULL ) {
		memcpy(&as->config, config, sizeof(as_config));
	}
	else {
		as_config_init(&as->config);
	}
	as_policies_resolve(&as->config.policies);
	return as;
}
static bool before(atf_plan * plan) {

    if ( as ) {
        error("aerospike was already initialized");
        return false;
    }

	// Initialize logging.
	as_log_set_level(AS_LOG_LEVEL_INFO);
	as_log_set_callback(as_client_log_callback);
	
	if (g_use_async) {
		if (as_event_create_loops(1) == 0) {
			error("failed to create event loops");
			return false;
		}
	}
	
	// Initialize global lua configuration.
	as_config_lua lua;
	as_config_lua_init(&lua);
	strcpy(lua.system_path, "modules/lua-core/src");
	strcpy(lua.user_path, "src/test/lua");
	aerospike_init_lua(&lua);

	// Initialize cluster configuration.
	as_config config;
	as_config_init(&config);
	as_config_add_host(&config, g_host, g_port);
	as_config_set_user(&config, g_user, g_password);
    as_policies_init(&config.policies);

	as_error err;
	as_error_reset(&err);

	as = aerospike_new(&config);

	if ( aerospike_connect(as, &err) == AEROSPIKE_OK ) {
		debug("connected to %s:%d", g_host, g_port);
    	return true;
	}
	else {
		error("%s @ %s[%s:%d]", err.message, err.func, err.file, err.line);
		return false;
	}
}
static bool before(atf_plan * plan) {

    if ( as ) {
        error("aerospike was already initialized");
        return false;
    }

    if (! parse_opts(g_argc, g_argv)) {
        error("failed to parse options");
    	return false;
    }
	
	as_log_set_level(AS_LOG_LEVEL_INFO);
	as_log_set_callback(as_client_log_callback);
	
	if (g_use_async) {
		if (as_event_create_loops(1) == 0) {
			error("failed to create event loops");
			return false;
		}
	}
	
	as_config config;
	as_config_init(&config);
	as_config_add_host(&config, g_host, g_port);
	as_config_set_user(&config, g_user, g_password);
	config.lua.cache_enabled = false;
	strcpy(config.lua.system_path, "modules/lua-core/src");
	strcpy(config.lua.user_path, "src/test/lua");
    as_policies_init(&config.policies);

	as_error err;
	as_error_reset(&err);

	as = aerospike_new(&config);

	if ( aerospike_connect(as, &err) == AEROSPIKE_OK ) {
		debug("connected to %s:%d", g_host, g_port);
    	return true;
	}
	else {
		error("%s @ %s[%s:%d]", err.message, err.func, err.file, err.line);
		return false;
	}
}
//------------------------------------------------
// Connect to database cluster, setting UDF
// configuration.
//
void
example_connect_to_aerospike_with_udf_config(aerospike* p_as,
		const char* lua_user_path)
{
	// Start with default configuration.
	as_config cfg;
	as_config_init(&cfg);
	as_config_add_host(&cfg, g_host, g_port);
	as_config_set_user(&cfg, g_user, g_password);

	// Examples can be run from client binary package-installed lua files or
	// from git client source tree lua files. If client binary package is not
	// installed, look for lua system files in client source tree.
	int rc = access(cfg.lua.system_path, R_OK);

	if (rc != 0) {
		// Use lua files in source tree if they exist.
		char* path = "../../../modules/lua-core/src";

		rc = access(path, R_OK);

		if (rc == 0) {
			strcpy(cfg.lua.system_path, path);
		}
	}

	if (lua_user_path) {
		strcpy(cfg.lua.user_path, lua_user_path);
	}

	aerospike_init(p_as, &cfg);

	as_error err;

	// Connect to the Aerospike database cluster. Assume this is the first thing
	// done after calling example_get_opts(), so it's ok to exit on failure.
	if (aerospike_connect(p_as, &err) != AEROSPIKE_OK) {
		LOG("aerospike_connect() returned %d - %s", err.code, err.message);
		aerospike_destroy(p_as);
		exit(-1);
	}
}
Exemple #7
0
// ----------------------------------------------------------------------------------
//
// def initialize(host, port, options = {})
//
static void client_initialize(int argc, VALUE * argv, VALUE self) {
  rb_aero_TIMED(tm);

  VALUE host;
  VALUE port;
  VALUE options;

  rb_scan_args(argc, argv, "21", &host, &port, &options);

  if ( NIL_P(options) ) options = rb_hash_new();

  rb_iv_set(self, "@host", host);
  rb_iv_set(self, "@port", port);
  rb_iv_set(self, "@last_scan_id", Qnil);
  rb_iv_set(self, "@last_query_id", Qnil);

  as_config config;
  as_config_init(&config);
  as_config_add_host(&config, StringValueCStr(host), FIX2INT(port));

  options2config(&config, options, self);
  rb_iv_set(self, "@options", options);

  aerospike * as;
  Data_Get_Struct(self, aerospike, as);

  aerospike_init(as, &config);

  as_error err;
  if (aerospike_connect(as, &err) != AEROSPIKE_OK) {
    aerospike_destroy(as);
    raise_as_error(err);
  }

  as_log_set_level(AS_LOG_LEVEL_DEBUG);

  VALUE option_tmp = rb_hash_aref(options, c_log_sym);

  if ( TYPE(option_tmp) == T_TRUE ) {
    as_log_set_callback(rb_aero_log_callback);
  }
}
bool asc_init(aerospike *p_as)
{
    as_status status;
    as_error err;

    // Start with default configuration.
    as_config cfg;
    as_config_init(&cfg);
    as_config_add_host(&cfg, HOST, PORT);
    as_config_set_user(&cfg, USER, PASS);
    aerospike_init(p_as, &cfg);

    // Connect to the Aerospike database cluster.
    status = aerospike_connect(p_as, &err);
    if (status != AEROSPIKE_OK) {
        ERROR("aerospike_connect() returned %d - %s", err.code, err.message);
        aerospike_destroy(p_as);
    }

    return (status == AEROSPIKE_OK);
}
Exemple #9
0
		bool AeroSpike::connect()
		{
			std::unique_lock<std::mutex> lock(connectMutex_);

			triedConnect_ = true;

			auto & configManager = adservice::server::ConfigManager::getInstance();
			auto * config = (adservice::server::AerospikeConfig *)configManager.get(CONFIG_AEROSPIKE);

			namespace_ = config->nameSpace;

			as_config_init(&config_);

			for (int i = 0; i < AS_CONFIG_HOSTS_SIZE && i < config->connections.size(); ++i) {
				config_.hosts[i].addr = config->connections[i].host.c_str();
				config_.hosts[i].port = config->connections[i].port;
			}

			if (aerospike_init(&connection_, &config_) == nullptr) {
				return false;
			}

			return (aerospike_connect(&connection_, &error_) == AEROSPIKE_OK);
		}
Exemple #10
0
int
main(int argc, char **argv)
{
	g_start_sec = cf_get_seconds();

	// Initialize cf_thread wrapper.
	cf_thread_init();

	// Initialize memory allocation.
	cf_alloc_init();

	// Initialize fault management framework.
	cf_fault_init();

	// Setup signal handlers.
	as_signal_setup();

	// Initialize TLS library.
	tls_check_init();

	int opt;
	int opt_i;
	const char *config_file = DEFAULT_CONFIG_FILE;
	bool run_in_foreground = false;
	bool new_style_daemon = false;
	bool cold_start_cmd = false;
	uint32_t instance = 0;

	// Parse command line options.
	while ((opt = getopt_long(argc, argv, "", CMD_OPTS, &opt_i)) != -1) {
		switch (opt) {
		case 'h':
			// printf() since we want stdout and don't want cf_fault's prefix.
			printf("%s\n", HELP);
			return 0;
		case 'v':
			// printf() since we want stdout and don't want cf_fault's prefix.
			printf("%s build %s\n", aerospike_build_type, aerospike_build_id);
			return 0;
		case 'f':
			config_file = cf_strdup(optarg);
			break;
		case 'F':
			// As a "new-style" daemon(*), asd runs in the foreground and
			// ignores the following configuration items:
			//  - user ('user')
			//	- group ('group')
			//  - PID file ('pidfile')
			//
			// If ignoring configuration items, or if the 'console' sink is not
			// specified, warnings will appear in stderr.
			//
			// (*) http://0pointer.de/public/systemd-man/daemon.html#New-Style%20Daemons
			run_in_foreground = true;
			new_style_daemon = true;
			break;
		case 'd':
			run_in_foreground = true;
			break;
		case 'c':
			cold_start_cmd = true;
			break;
		case 'n':
			instance = (uint32_t)strtol(optarg, NULL, 0);
			break;
		default:
			// fprintf() since we don't want cf_fault's prefix.
			fprintf(stderr, "%s\n", USAGE);
			return 1;
		}
	}

	// Set all fields in the global runtime configuration instance. This parses
	// the configuration file, and creates as_namespace objects. (Return value
	// is a shortcut pointer to the global runtime configuration instance.)
	as_config *c = as_config_init(config_file);

	// Detect NUMA topology and, if requested, prepare for CPU and NUMA pinning.
	cf_topo_config(c->auto_pin, (cf_topo_numa_node_index)instance,
			&c->service.bind);

	// Perform privilege separation as necessary. If configured user & group
	// don't have root privileges, all resources created or reopened past this
	// point must be set up so that they are accessible without root privileges.
	// If not, the process will self-terminate with (hopefully!) a log message
	// indicating which resource is not set up properly.
	cf_process_privsep(c->uid, c->gid);

	//
	// All resources such as files, devices, and shared memory must be created
	// or reopened below this line! (The configuration file is the only thing
	// that must be opened above, in order to parse the user & group.)
	//==========================================================================

	// A "new-style" daemon expects console logging to be configured. (If not,
	// log messages won't be seen via the standard path.)
	if (new_style_daemon) {
		if (! cf_fault_console_is_held()) {
			cf_warning(AS_AS, "in new-style daemon mode, console logging is not configured");
		}
	}

	// Activate log sinks. Up to this point, 'cf_' log output goes to stderr,
	// filtered according to NO_SINKS_LIMIT in fault.c. After this point, 'cf_'
	// log output will appear in all log file sinks specified in configuration,
	// with specified filtering. If console sink is specified in configuration,
	// 'cf_' log output will continue going to stderr, but filtering will switch
	// from NO_SINKS_LIMIT to that specified in console sink configuration.
	if (0 != cf_fault_sink_activate_all_held()) {
		// Specifics of failure are logged in cf_fault_sink_activate_all_held().
		cf_crash_nostack(AS_AS, "can't open log sink(s)");
	}

	// Daemonize asd if specified. After daemonization, output to stderr will no
	// longer appear in terminal. Instead, check /tmp/aerospike-console.<pid>
	// for console output.
	if (! run_in_foreground && c->run_as_daemon) {
		// Don't close any open files when daemonizing. At this point only log
		// sink files are open - instruct cf_process_daemonize() to ignore them.
		int open_fds[CF_FAULT_SINKS_MAX];
		int num_open_fds = cf_fault_sink_get_fd_list(open_fds);

		cf_process_daemonize(open_fds, num_open_fds);
	}

	// Log which build this is - should be the first line in the log file.
	cf_info(AS_AS, "<><><><><><><><><><>  %s build %s  <><><><><><><><><><>",
			aerospike_build_type, aerospike_build_id);

	// Includes echoing the configuration file to log.
	as_config_post_process(c, config_file);

	xdr_config_post_process();

	// If we allocated a non-default config file name, free it.
	if (config_file != DEFAULT_CONFIG_FILE) {
		cf_free((void*)config_file);
	}

	// Write the pid file, if specified.
	if (! new_style_daemon) {
		write_pidfile(c->pidfile);
	}
	else {
		if (c->pidfile) {
			cf_warning(AS_AS, "will not write PID file in new-style daemon mode");
		}
	}

	// Check that required directories are set up properly.
	validate_directory(c->work_directory, "work");
	validate_directory(c->mod_lua.user_path, "Lua user");
	validate_smd_directory();

	// Initialize subsystems. At this point we're allocating local resources,
	// starting worker threads, etc. (But no communication with other server
	// nodes or clients yet.)

	as_json_init();				// Jansson JSON API used by System Metadata
	as_index_tree_gc_init();	// thread to purge dropped index trees
	as_sindex_thr_init();		// defrag secondary index (ok during population)
	as_nsup_init();				// load previous evict-void-time(s)

	// Initialize namespaces. Each namespace decides here whether it will do a
	// warm or cold start. Index arenas, partition structures and index tree
	// structures are initialized. Secondary index system metadata is restored.
	as_namespaces_init(cold_start_cmd, instance);

	// Initialize the storage system. For warm and cool restarts, this includes
	// fully resuming persisted indexes - this may take a few minutes.
	as_storage_init();

	// Migrate memory to correct NUMA node (includes resumed index arenas).
	cf_topo_migrate_memory();

	// Drop capabilities that we kept only for initialization.
	cf_process_drop_startup_caps();

	// Activate the storage system. For cold starts and cool restarts, this
	// includes full drive scans - this may take several hours. The defrag
	// subsystem starts operating at the end of this call.
	as_storage_load();

	// Populate all secondary indexes. This may block for a long time.
	as_sindex_boot_populateall();

	cf_info(AS_AS, "initializing services...");

	cf_dns_init();				// DNS resolver
	as_netio_init();			// query responses
	as_security_init();			// security features
	as_tsvc_init();				// all transaction handling
	as_hb_init();				// inter-node heartbeat
	as_skew_monitor_init();		// clock skew monitor
	as_fabric_init();			// inter-node communications
	as_exchange_init();			// initialize the cluster exchange subsystem
	as_clustering_init();		// clustering-v5 start
	as_info_init();				// info transaction handling
	as_migrate_init();			// move data between nodes
	as_proxy_init();			// do work on behalf of others
	as_rw_init();				// read & write service
	as_query_init();			// query transaction handling
	as_udf_init();				// user-defined functions
	as_scan_init();				// scan a namespace or set
	as_batch_init();			// batch transaction handling
	as_xdr_init();				// cross data-center replication
	as_mon_init();				// monitor

	// Wait for enough available storage. We've been defragging all along, but
	// here we wait until it's enough. This may block for a long time.
	as_storage_wait_for_defrag();

	// Start subsystems. At this point we may begin communicating with other
	// cluster nodes, and ultimately with clients.

	as_smd_start();				// enables receiving cluster state change events
	as_health_start();			// starts before fabric and hb to capture them
	as_fabric_start();			// may send & receive fabric messages
	as_xdr_start();				// XDR should start before it joins other nodes
	as_hb_start();				// start inter-node heartbeat
	as_exchange_start();		// start the cluster exchange subsystem
	as_clustering_start();		// clustering-v5 start
	as_nsup_start();			// may send evict-void-time(s) to other nodes
	as_service_start();			// server will now receive client transactions
	as_info_port_start();		// server will now receive info transactions
	as_ticker_start();			// only after everything else is started

	// Relevant for enterprise edition only.
	as_storage_start_tomb_raider();

	// Log a service-ready message.
	cf_info(AS_AS, "service ready: soon there will be cake!");

	//--------------------------------------------
	// Startup is done. This thread will now wait
	// quietly for a shutdown signal.
	//

	// Stop this thread from finishing. Intentionally deadlocking on a mutex is
	// a remarkably efficient way to do this.
	pthread_mutex_lock(&g_main_deadlock);
	g_startup_complete = true;
	pthread_mutex_lock(&g_main_deadlock);

	// When the service is running, you are here (deadlocked) - the signals that
	// stop the service (yes, these signals always occur in this thread) will
	// unlock the mutex, allowing us to continue.

	g_shutdown_started = true;
	pthread_mutex_unlock(&g_main_deadlock);
	pthread_mutex_destroy(&g_main_deadlock);

	//--------------------------------------------
	// Received a shutdown signal.
	//

	as_storage_shutdown(instance);
	as_xdr_shutdown();

	cf_info(AS_AS, "finished clean shutdown - exiting");

	// If shutdown was totally clean (all threads joined) we could just return,
	// but for now we exit to make sure all threads die.
#ifdef DOPROFILE
	exit(0); // exit(0) so profile build actually dumps gmon.out
#else
	_exit(0);
#endif

	return 0;
}
Exemple #11
0
int
main(int argc, char **argv)
{
#ifdef USE_ASM
	as_mallocation_t asm_array[MAX_NUM_MALLOCATIONS];

	// Zero-out the statically-allocated array of memory allocation locations.
	memset(asm_array, 0, sizeof(asm_array));

	// Set the ASMalloc callback user data.
	g_my_cb_udata = asm_array;

	// This must come first to allow initialization of the ASMalloc library.
	asm_init();
#endif // defined(USE_ASM)

#ifdef USE_JEM
	// Initialize the JEMalloc interface.
	jem_init(true);
#endif

	// Initialize ref-counting system.
	cf_rc_init(NULL);

	// Initialize fault management framework.
	cf_fault_init();

	// Setup signal handlers.
	as_signal_setup();

	// Initialize the Jansson JSON API.
	as_json_init();

	int i;
	int cmd_optidx;
	const char *config_file = DEFAULT_CONFIG_FILE;
	bool run_in_foreground = false;
	bool cold_start_cmd = false;
	uint32_t instance = 0;

	// Parse command line options.
	while (-1 != (i = getopt_long(argc, argv, "", cmd_opts, &cmd_optidx))) {
		switch (i) {
		case 'h':
			// printf() since we want stdout and don't want cf_fault's prefix.
			printf("%s\n", HELP);
			return 0;
		case 'v':
			// printf() since we want stdout and don't want cf_fault's prefix.
			printf("%s build %s\n", aerospike_build_type, aerospike_build_id);
			return 0;
		case 'f':
			config_file = cf_strdup(optarg);
			cf_assert(config_file, AS_AS, CF_CRITICAL, "config filename cf_strdup failed");
			break;
		case 'd':
			run_in_foreground = true;
			break;
		case 'c':
			cold_start_cmd = true;
			break;
		case 'n':
			instance = (uint32_t)strtol(optarg, NULL, 0);
			break;
		default:
			// fprintf() since we don't want cf_fault's prefix.
			fprintf(stderr, "%s\n", USAGE);
			return 1;
		}
	}

	// Set all fields in the global runtime configuration instance. This parses
	// the configuration file, and creates as_namespace objects. (Return value
	// is a shortcut pointer to the global runtime configuration instance.)
	as_config *c = as_config_init(config_file);

#ifdef USE_ASM
	g_asm_hook_enabled = g_asm_cb_enabled = c->asmalloc_enabled;

	long initial_tid = syscall(SYS_gettid);
#endif

#ifdef MEM_COUNT
	// [Note: This should ideally be at the very start of the "main()" function,
	//        but we need to wait until after the config file has been parsed in
	//        order to support run-time configurability.]
	mem_count_init(c->memory_accounting ? MEM_COUNT_ENABLE : MEM_COUNT_DISABLE);
#endif

	// Perform privilege separation as necessary. If configured user & group
	// don't have root privileges, all resources created or reopened past this
	// point must be set up so that they are accessible without root privileges.
	// If not, the process will self-terminate with (hopefully!) a log message
	// indicating which resource is not set up properly.
	if (0 != c->uid && 0 == geteuid()) {
		// To see this log, change NO_SINKS_LIMIT in fault.c:
		cf_info(AS_AS, "privsep to %d %d", c->uid, c->gid);
		cf_process_privsep(c->uid, c->gid);
	}

	//
	// All resources such as files, devices, and shared memory must be created
	// or reopened below this line! (The configuration file is the only thing
	// that must be opened above, in order to parse the user & group.)
	//==========================================================================

	// Activate log sinks. Up to this point, 'cf_' log output goes to stderr,
	// filtered according to NO_SINKS_LIMIT in fault.c. After this point, 'cf_'
	// log output will appear in all log file sinks specified in configuration,
	// with specified filtering. If console sink is specified in configuration,
	// 'cf_' log output will continue going to stderr, but filtering will switch
	// from NO_SINKS_LIMIT to that specified in console sink configuration.
	if (0 != cf_fault_sink_activate_all_held()) {
		// Specifics of failure are logged in cf_fault_sink_activate_all_held().
		cf_crash_nostack(AS_AS, "can't open log sink(s)");
	}

	// Daemonize asd if specified. After daemonization, output to stderr will no
	// longer appear in terminal. Instead, check /tmp/aerospike-console.<pid>
	// for console output.
	if (! run_in_foreground && c->run_as_daemon) {
		// Don't close any open files when daemonizing. At this point only log
		// sink files are open - instruct cf_process_daemonize() to ignore them.
		int open_fds[CF_FAULT_SINKS_MAX];
		int num_open_fds = cf_fault_sink_get_fd_list(open_fds);

		cf_process_daemonize(open_fds, num_open_fds);
	}

#ifdef USE_ASM
	// Log the main thread's Linux Task ID (pre- and post-fork) to the console.
	fprintf(stderr, "Initial main thread tid: %lu\n", initial_tid);

	if (! run_in_foreground && c->run_as_daemon) {
		fprintf(stderr, "Post-daemonize main thread tid: %lu\n",
				syscall(SYS_gettid));
	}
#endif

	// Log which build this is - should be the first line in the log file.
	cf_info(AS_AS, "<><><><><><><><><><>  %s build %s  <><><><><><><><><><>",
			aerospike_build_type, aerospike_build_id);

	// Includes echoing the configuration file to log.
	as_config_post_process(c, config_file);

	// If we allocated a non-default config file name, free it.
	if (config_file != DEFAULT_CONFIG_FILE) {
		cf_free((void*)config_file);
	}

	// Write the pid file, if specified.
	write_pidfile(c->pidfile);

	// Check that required directories are set up properly.
	validate_directory(c->work_directory, "work");
	validate_directory(c->mod_lua.system_path, "Lua system");
	validate_directory(c->mod_lua.user_path, "Lua user");
	validate_smd_directory();

	// Initialize subsystems. At this point we're allocating local resources,
	// starting worker threads, etc. (But no communication with other server
	// nodes or clients yet.)

	as_smd_init();				// System Metadata first - others depend on it
	ai_init();					// before as_storage_init() populates indexes
	as_sindex_thr_init();		// defrag secondary index (ok during population)

	// Initialize namespaces. Each namespace decides here whether it will do a
	// warm or cold start. Index arenas, partition structures and index tree
	// structures are initialized. Secondary index system metadata is restored.
	as_namespaces_init(cold_start_cmd, instance);

	// Initialize the storage system. For cold starts, this includes reading
	// all the objects off the drives. This may block for a long time. The
	// defrag subsystem starts operating at the end of this call.
	as_storage_init();

	// Populate all secondary indexes. This may block for a long time.
	as_sindex_boot_populateall();

	cf_info(AS_AS, "initializing services...");

	as_netio_init();
	as_security_init();			// security features
	as_tsvc_init();				// all transaction handling
	as_hb_init();				// inter-node heartbeat
	as_fabric_init();			// inter-node communications
	as_info_init();				// info transaction handling
	as_paxos_init();			// cluster consensus algorithm
	as_migrate_init();			// move data between nodes
	as_proxy_init();			// do work on behalf of others
	as_write_init();			// write service
	as_query_init();			// query transaction handling
	as_udf_init();				// apply user-defined functions
	as_scan_init();				// scan a namespace or set
	as_batch_init();			// batch transaction handling
	as_batch_direct_init();		// low priority transaction handling        
	as_xdr_init();				// cross data-center replication
	as_mon_init();				// monitor

	// Wait for enough available storage. We've been defragging all along, but
	// here we wait until it's enough. This may block for a long time.
	as_storage_wait_for_defrag();

	// Start subsystems. At this point we may begin communicating with other
	// cluster nodes, and ultimately with clients.

	as_smd_start(c->smd);		// enables receiving paxos state change events
	as_fabric_start();			// may send & receive fabric messages
	as_hb_start();				// start inter-node heatbeat
	as_paxos_start();			// blocks until cluster membership is obtained
	as_nsup_start();			// may send delete transactions to other nodes
	as_demarshal_start();		// server will now receive client transactions
	as_info_port_start();		// server will now receive info transactions
	info_debug_ticker_start();	// only after everything else is started

	// Log a service-ready message.
	cf_info(AS_AS, "service ready: soon there will be cake!");

	//--------------------------------------------
	// Startup is done. This thread will now wait
	// quietly for a shutdown signal.
	//

	// Stop this thread from finishing. Intentionally deadlocking on a mutex is
	// a remarkably efficient way to do this.
	pthread_mutex_init(&g_NONSTOP, NULL);
	pthread_mutex_lock(&g_NONSTOP);
	g_startup_complete = true;
	pthread_mutex_lock(&g_NONSTOP);

	// When the service is running, you are here (deadlocked) - the signals that
	// stop the service (yes, these signals always occur in this thread) will
	// unlock the mutex, allowing us to continue.

	g_shutdown_started = true;
	pthread_mutex_unlock(&g_NONSTOP);
	pthread_mutex_destroy(&g_NONSTOP);

	//--------------------------------------------
	// Received a shutdown signal.
	//

	as_storage_shutdown();
	as_xdr_shutdown();
	as_smd_shutdown(c->smd);

	cf_info(AS_AS, "finished clean shutdown - exiting");

	// If shutdown was totally clean (all threads joined) we could just return,
	// but for now we exit to make sure all threads die.
#ifdef DOPROFILE
	exit(0); // exit(0) so profile build actually dumps gmon.out
#else
	_exit(0);
#endif

	return 0;
}
Exemple #12
0
static int AerospikeClient_Type_Init(AerospikeClient * self, PyObject * args, PyObject * kwds)
{
	PyObject * py_config = NULL;

	static char * kwlist[] = {"config", NULL};

	if ( PyArg_ParseTupleAndKeywords(args, kwds, "O:client", kwlist, &py_config) == false ) {
		return -1;
	}

	if ( ! PyDict_Check(py_config) ) {
		return -1;
	}

	as_config config;
	as_config_init(&config);

	bool lua_system_path = FALSE;
	bool lua_user_path = FALSE;

	PyObject * py_lua = PyDict_GetItemString(py_config, "lua");
	if ( py_lua && PyDict_Check(py_lua) ) {

		PyObject * py_lua_system_path = PyDict_GetItemString(py_lua, "system_path");
		if ( py_lua_system_path && PyString_Check(py_lua_system_path) ) {
			lua_system_path = TRUE;
			memcpy(config.lua.system_path, PyString_AsString(py_lua_system_path), AS_CONFIG_PATH_MAX_LEN);
		}

		PyObject * py_lua_user_path = PyDict_GetItemString(py_lua, "user_path");
		if ( py_lua_user_path && PyString_Check(py_lua_user_path) ) {
			lua_user_path = TRUE;
			memcpy(config.lua.user_path, PyString_AsString(py_lua_user_path), AS_CONFIG_PATH_MAX_LEN);
		}

	}

	if ( ! lua_system_path ) {

		PyObject * py_prefix = PySys_GetObject("prefix");
		if ( py_prefix && PyString_Check(py_prefix) ) {
			char * prefix = PyString_AsString(py_prefix);
			size_t prefix_len = strlen(prefix);

			char system_path[AS_CONFIG_PATH_MAX_LEN] = {0};
			memcpy(system_path, prefix, strlen(prefix));
			memcpy(system_path + prefix_len, "/aerospike/lua", AS_CONFIG_PATH_MAX_LEN - prefix_len);
			system_path[prefix_len + strlen("/aerospike/lua")] = '\0';

			struct stat info;

			if( stat( system_path, &info ) == 0 && (info.st_mode & S_IFDIR) ) {
				memcpy(config.lua.system_path, system_path, AS_CONFIG_PATH_MAX_LEN);
			}
			else {
				memcpy(system_path + prefix_len, "/local/aerospike/lua", AS_CONFIG_PATH_MAX_LEN - prefix_len);
				system_path[prefix_len + strlen("/local/aerospike/lua")] = '\0';

				if( stat( system_path, &info ) == 0 && (info.st_mode & S_IFDIR) ) {
					memcpy(config.lua.system_path, system_path, AS_CONFIG_PATH_MAX_LEN);
				}
				else {
					config.lua.system_path[0] = '\0';
				}
			}
		}
	}

	if ( ! lua_user_path ) {
		memcpy(config.lua.user_path, ".", AS_CONFIG_PATH_MAX_LEN);
	}

	PyObject * py_hosts = PyDict_GetItemString(py_config, "hosts");
	if ( py_hosts && PyList_Check(py_hosts) ) {
		int size = (int) PyList_Size(py_hosts);
		for ( int i = 0; i < size && i < AS_CONFIG_HOSTS_SIZE; i++ ) {
			char *addr = NULL;
			uint16_t port = 3000;
			PyObject * py_host = PyList_GetItem(py_hosts, i);
			PyObject * py_addr, * py_port;

			if( PyTuple_Check(py_host) && PyTuple_Size(py_host) == 2) {

				py_addr = PyTuple_GetItem(py_host, 0);
				if(PyString_Check(py_addr)) {
					addr = strdup(PyString_AsString(py_addr));
				}
				py_port = PyTuple_GetItem(py_host,1);
				if( PyInt_Check(py_port) || PyLong_Check(py_port) ) {
					port = (uint16_t) PyLong_AsLong(py_port);
				}
				else {
					port = 0;
				}
			}
			else if ( PyString_Check(py_host) ) {
				addr = strdup( strtok( PyString_AsString(py_host), ":" ) );
				addr = strtok(addr, ":");
				char *temp = strtok(NULL, ":");
				if(NULL != temp) {
					port = (uint16_t)atoi(temp);
				}
			}
			as_config_add_host(&config, addr, port);
		}
	}

    PyObject * py_shm = PyDict_GetItemString(py_config, "shm");
    if (py_shm && PyDict_Check(py_shm) ) {

        config.use_shm = true;

        PyObject * py_shm_max_nodes = PyDict_GetItemString( py_shm, "shm_max_nodes" );
        if(py_shm_max_nodes && PyInt_Check(py_shm_max_nodes) ) {
            config.shm_max_nodes = PyInt_AsLong(py_shm_max_nodes);
        }

        PyObject * py_shm_max_namespaces = PyDict_GetItemString(py_shm, "shm_max_namespaces");
        if(py_shm_max_namespaces && PyInt_Check(py_shm_max_namespaces) ) {
            config.shm_max_namespaces = PyInt_AsLong(py_shm_max_namespaces);
        }

        PyObject* py_shm_takeover_threshold_sec = PyDict_GetItemString(py_shm, "shm_takeover_threshold_sec");
        if(py_shm_takeover_threshold_sec && PyInt_Check(py_shm_takeover_threshold_sec) ) {
            config.shm_takeover_threshold_sec = PyInt_AsLong( py_shm_takeover_threshold_sec);
        }
    }

    self->is_client_put_serializer = false;
    self->user_serializer_call_info.callback = NULL;
    self->user_deserializer_call_info.callback = NULL;
    PyObject *py_serializer_option = PyDict_GetItemString(py_config, "serialization");
    if (py_serializer_option && PyTuple_Check(py_serializer_option)) {
        PyObject *py_serializer = PyTuple_GetItem(py_serializer_option, 0);
        if (py_serializer && py_serializer != Py_None) {
            if (!PyCallable_Check(py_serializer)) {
                return -1;
            }
            memset(&self->user_serializer_call_info, 0, sizeof(self->user_serializer_call_info));
            self->user_serializer_call_info.callback = py_serializer;
        }
        PyObject *py_deserializer = PyTuple_GetItem(py_serializer_option, 1);
        if (py_deserializer && py_deserializer != Py_None) {
            if (!PyCallable_Check(py_deserializer)) {
                return -1;
            }
            memset(&self->user_deserializer_call_info, 0, sizeof(self->user_deserializer_call_info));
            self->user_deserializer_call_info.callback = py_deserializer;
        }
    }

	as_policies_init(&config.policies);

	PyObject * py_policies = PyDict_GetItemString(py_config, "policies");
	if ( py_policies && PyDict_Check(py_policies)) {
		//global defaults setting
		PyObject * py_key_policy = PyDict_GetItemString(py_policies, "key");
		if ( py_key_policy && PyInt_Check(py_key_policy) ) {
			config.policies.key = PyInt_AsLong(py_key_policy);
		}

		PyObject * py_timeout = PyDict_GetItemString(py_policies, "timeout");
		if ( py_timeout && PyInt_Check(py_timeout) ) {
			config.policies.timeout = PyInt_AsLong(py_timeout);
		}

		PyObject * py_retry = PyDict_GetItemString(py_policies, "retry");
		if ( py_retry && PyInt_Check(py_retry) ) {
			config.policies.retry = PyInt_AsLong(py_retry);
		}

		PyObject * py_exists = PyDict_GetItemString(py_policies, "exists");
		if ( py_exists && PyInt_Check(py_exists) ) {
			config.policies.exists = PyInt_AsLong(py_exists);
		}

		PyObject * py_replica = PyDict_GetItemString(py_policies, "replica");
		if ( py_replica && PyInt_Check(py_replica) ) {
			config.policies.replica = PyInt_AsLong(py_replica);
		}

		PyObject * py_consistency_level = PyDict_GetItemString(py_policies, "consistency_level");
		if ( py_consistency_level && PyInt_Check(py_consistency_level) ) {
			config.policies.consistency_level = PyInt_AsLong(py_consistency_level);
		}

		PyObject * py_commit_level = PyDict_GetItemString(py_policies, "commit_level");
		if ( py_commit_level && PyInt_Check(py_commit_level) ) {
			config.policies.commit_level = PyInt_AsLong(py_commit_level);
		}

		/*
		 * Generation policy is removed from constructor.
		 */
	}

	//conn_timeout_ms
	PyObject * py_connect_timeout = PyDict_GetItemString(py_config, "connect_timeout");
	if ( py_connect_timeout && PyInt_Check(py_connect_timeout) ) {
		config.conn_timeout_ms = PyInt_AsLong(py_connect_timeout);
	}

	self->as = aerospike_new(&config);

	return 0;
}