blob: 307982f76f4351abef522d49f52682b3183296d7 [file] [log] [blame]
/*
* The MIT License (MIT)
*
* Copyright (c) 2015 Microsoft Corporation
*
* -=- Robust Distributed System Nucleus (rDSN) -=-
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// service API for app/framework development,
// including threading/tasking, thread synchronization,
// RPC, asynchronous file IO, environment, etc.
#pragma once
#include "common/gpid.h"
#include "rpc/rpc_address.h"
#include "rpc/rpc_host_port.h"
#include "runtime/api_task.h"
#include "task/task_tracker.h"
/*!
@defgroup service-api-c Core Service API
@ingroup service-api
Core service API for building applications and distributed frameworks, which
covers the major categories that a server application may use, shown in the modules below.
@{
*/
/*!
@defgroup task-common Common Task Operations
Common Task/Event Operations
rDSN adopts the event-driven programming model, where all computations (event handlers) are
represented as individual tasks; each is the execution of a sequential piece of code in one thread.
Specifically, rDSN categorizes the tasks into four types, as defined in \ref dsn_task_type_t.
Unlike the traditional event-driven programming, rDSN enhances the model in the following ways,
with which they control the application in many aspects in a declarative approach.
- each task is labeled with a task code, with which developers can configure many aspects in config
files.
Developers can define new task code using \ref DEFINE_TASK_CODE, or \ref dsn_task_code_register.
<PRE>
[task..default]
; allow task executed in other thread pools or tasks
; for TASK_TYPE_COMPUTE - allow-inline allows a task being executed in its caller site
; for other tasks - allow-inline allows a task being execution in io-thread
allow_inline = false
; group rpc mode with group address: GRPC_TO_LEADER, GRPC_TO_ALL, GRPC_TO_ANY
grpc_mode = GRPC_TO_LEADER
; when toollet profiler is enabled
is_profile = true
; when toollet tracer is enabled
is_trace = true
; thread pool to execute the task
pool_code = THREAD_POOL_DEFAULT
; task priority
priority = TASK_PRIORITY_COMMON
; whether to randomize the timer delay to random(0, timer_interval),
; if the initial delay is zero, to avoid multiple timers executing at the same time (e.g.,
checkpointing)
randomize_timer_delay_if_zero = false
; what kind of network channel for this kind of rpc calls
rpc_call_channel = RPC_CHANNEL_TCP
; what kind of header format for this kind of rpc calls
rpc_call_header_format = NET_HDR_DSN
; how many milliseconds to delay recving rpc session for
; when queue length ~= [1.0, 1.2, 1.4, 1.6, 1.8, >=2.0] x pool.queue_length_throttling_threshold,
; e.g., 0, 0, 1, 2, 5, 10
rpc_request_delays_milliseconds = 0, 0, 1, 2, 5, 10
; whether to drop a request right before execution when its queueing time
; is already greater than its timeout value
rpc_request_dropped_before_execution_when_timeout = false
; for how long (ms) the request will be resent if no response
; is received yet, 0 for disable this feature
rpc_request_resend_timeout_milliseconds = 0
; throttling mode for rpc requets: TM_NONE, TM_REJECT, TM_DELAY when
; queue length > pool.queue_length_throttling_threshold
rpc_request_throttling_mode = TM_NONE
; what is the default timeout (ms) for this kind of rpc calls
rpc_timeout_milliseconds = 5000
[task.LPC_AIO_IMMEDIATE_CALLBACK]
; override the option in [task..default]
allow_inline = true
</PRE>
- each task code is bound to a thread pool, which can be customized as follows.
Developers can define new thread pools using \ref DEFINE_THREAD_POOL_CODE, or \ref
dsn_threadpool_code_register.
<PRE>
[threadpool..default]
; how many tasks (if available) should be returned for
; one dequeue call for best batching performance
dequeue_batch_size = 5
; throttling: whether to enable throttling with virtual queues
enable_virtual_queue_throttling = false
; thread pool name
name = THREAD_POOL_INVALID
; whethe the threads share a single queue(partitioned=false) or not;
; the latter is usually for workload hash partitioning for avoiding locking
partitioned = false
; task queue aspects names, usually for tooling purpose
queue_aspects =
; task queue provider name
queue_factory_name = dsn::tools::hpc_concurrent_task_queue
; throttling: throttling threshold above which rpc requests will be dropped
queue_length_throttling_threshold = 1000000
; what CPU cores are assigned to this pool, 0 for all
worker_affinity_mask = 0
; task aspects names, usually for tooling purpose
worker_aspects =
; thread/worker count
worker_count = 2
; task worker provider name
worker_factory_name =
; thread priority
worker_priority = THREAD_xPRIORITY_NORMAL
; whether the threads share all assigned cores
worker_share_core = true
[threadpool.THREAD_POOL_DEFAULT]
; override default options in [threadpool..default]
dequeue_batch_size = 5
</PRE>
-
@{
*/
/*! cancel the later execution of the timer task inside the timer */
extern void dsn_task_cancel_current_timer();
/*!
check whether the task is currently running inside the given task
\param t the given task handle
\return true if it is.
*/
extern bool dsn_task_is_running_inside(dsn::task *t);
/*@}*/
/*!
@defgroup tasking Asynchronous Tasks and Timers
Asynchronous Tasks and Timers
@{
*/
/*!
@defgroup rpc Remote Procedure Call (RPC)
Remote Procedure Call (RPC)
Note developers can easily plugin their own implementation to
replace the underneath implementation of the network (e.g., RDMA, simulated network)
@{
*/
/*!
@{
*/
extern dsn::rpc_address dsn_primary_address();
extern dsn::host_port dsn_primary_host_port();
/*!
@defgroup rpc-server Server-Side RPC Primitives
Server-Side RPC Primitives
@{
*/
/*! register callback to handle RPC request */
extern bool dsn_rpc_register_handler(dsn::task_code code,
const char *extra_name,
const dsn::rpc_request_handler &cb);
/*! unregister callback to handle RPC request, returns true if unregister ok, false if no handler
was registered */
extern bool dsn_rpc_unregiser_handler(dsn::task_code code);
/*! reply with a response which is created using dsn::message_ex::create_response */
extern void dsn_rpc_reply(dsn::message_ex *response, dsn::error_code err = dsn::ERR_OK);
/*! forward the request to another server instead */
extern void dsn_rpc_forward(dsn::message_ex *request, dsn::rpc_address addr);
/*@}*/
/*!
@defgroup rpc-client Client-Side RPC Primitives
Client-Side RPC Primitives
@{
*/
/*! client invokes the RPC call */
extern void dsn_rpc_call(dsn::rpc_address server, dsn::rpc_response_task *rpc_call);
/*!
client invokes the RPC call and waits for its response, note
returned msg must be explicitly released using \ref dsn::message_ex::release_ref
*/
extern dsn::message_ex *dsn_rpc_call_wait(dsn::rpc_address server, dsn::message_ex *request);
/*! one-way RPC from client, no rpc response is expected */
extern void dsn_rpc_call_one_way(dsn::rpc_address server, dsn::message_ex *request);
/*@}*/
/*@}*/
extern uint64_t dsn_now_ns();
__inline uint64_t dsn_now_us() { return dsn_now_ns() / 1000; }
__inline uint64_t dsn_now_ms() { return dsn_now_ns() / 1000000; }
__inline uint64_t dsn_now_s() { return dsn_now_ns() / 1000000000; }
/*@}*/
/*@}*/
/*@}*/