Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
0d54c5a3
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0d54c5a3
编写于
9月 26, 2022
作者:
Z
zhihaop
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: sql objects merging and sending are asynchronous
上级
e2a029ca
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
136 addition
and
98 deletion
+136
-98
src/client/inc/tscBatchWrite.h
src/client/inc/tscBatchWrite.h
+24
-11
src/client/src/tscBatchWrite.c
src/client/src/tscBatchWrite.c
+112
-87
未找到文件。
src/client/inc/tscBatchWrite.h
浏览文件 @
0d54c5a3
...
@@ -36,7 +36,7 @@ typedef struct SDispatcherTimeoutManager SDispatcherTimeoutManager;
...
@@ -36,7 +36,7 @@ typedef struct SDispatcherTimeoutManager SDispatcherTimeoutManager;
typedef
struct
SAsyncBatchWriteDispatcher
{
typedef
struct
SAsyncBatchWriteDispatcher
{
// the client object.
// the client object.
STscObj
*
pClient
;
STscObj
*
pClient
;
// the timeout manager.
// the timeout manager.
SDispatcherTimeoutManager
*
timeoutManager
;
SDispatcherTimeoutManager
*
timeoutManager
;
...
@@ -80,7 +80,7 @@ typedef struct SDispatcherManager {
...
@@ -80,7 +80,7 @@ typedef struct SDispatcherManager {
// the global dispatcher, if thread local enabled, global will be set to NULL.
// the global dispatcher, if thread local enabled, global will be set to NULL.
SAsyncBatchWriteDispatcher
*
pGlobal
;
SAsyncBatchWriteDispatcher
*
pGlobal
;
// the client object.
// the client object.
STscObj
*
pClient
;
STscObj
*
pClient
;
...
@@ -109,6 +109,14 @@ typedef struct SDispatcherTimeoutManager {
...
@@ -109,6 +109,14 @@ typedef struct SDispatcherTimeoutManager {
volatile
bool
shutdown
;
volatile
bool
shutdown
;
}
SDispatcherTimeoutManager
;
}
SDispatcherTimeoutManager
;
/**
* A batch that polls from SAsyncBatchWriteDispatcher::buffer.
*/
typedef
struct
SBatchRequest
{
size_t
nRequests
;
SSqlObj
*
pRequests
[];
}
SBatchRequest
;
/**
/**
* Create the dispatcher timeout manager.
* Create the dispatcher timeout manager.
*/
*/
...
@@ -135,20 +143,25 @@ void shutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager);
...
@@ -135,20 +143,25 @@ void shutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager);
/**
/**
* Merge SSqlObjs into single SSqlObj.
* Merge SSqlObjs into single SSqlObj.
*
*
* @param polls the array of SSqlObj*.
* @param pRequest the batch request.
* @param nPolls the number of SSqlObj* in the array.
* @param batch the batch SSqlObj*.
* @param batch the merged SSqlObj*.
* @return the status code.
* @return the merged SSqlObj.
*/
*/
int32_t
dispatcherBatchBuilder
(
SSqlObj
**
polls
,
size_t
nPolls
,
SSqlObj
**
batch
);
int32_t
dispatcherBatchBuilder
(
SBatchRequest
*
pRequest
,
SSqlObj
**
batch
);
/**
* Merge the sql statements and execute the merged sql statement asynchronously.
*
* @param pRequest the batch request. the request will be promised to free after calling this function.
*/
void
dispatcherAsyncExecute
(
SBatchRequest
*
pRequest
);
/**
/**
* Merge the sql statements and execute the merged sql statement.
* Merge the sql statements and execute the merged sql statement.
*
*
* @param polls the array of SSqlObj*.
* @param pRequest the batch request. you must call free(pRequest) after calling this function.
* @param nPolls the number of SSqlObj* in the array.
*/
*/
void
dispatcherExecute
(
S
SqlObj
**
polls
,
size_t
nPolls
);
void
dispatcherExecute
(
S
BatchRequest
*
pRequest
);
/**
/**
* Create the async batch write dispatcher.
* Create the async batch write dispatcher.
...
@@ -190,7 +203,7 @@ bool dispatcherTryDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql
...
@@ -190,7 +203,7 @@ bool dispatcherTryDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql
/**
/**
* Create the manager of SAsyncBatchWriteDispatcher.
* Create the manager of SAsyncBatchWriteDispatcher.
*
*
* @param pClient the client object.
* @param pClient the client object.
* @param batchSize the batchSize of SAsyncBatchWriteDispatcher.
* @param batchSize the batchSize of SAsyncBatchWriteDispatcher.
* @param timeoutMs the timeoutMs of SAsyncBatchWriteDispatcher.
* @param timeoutMs the timeoutMs of SAsyncBatchWriteDispatcher.
...
...
src/client/src/tscBatchWrite.c
浏览文件 @
0d54c5a3
...
@@ -17,9 +17,9 @@
...
@@ -17,9 +17,9 @@
#include "tscBatchMerge.h"
#include "tscBatchMerge.h"
#include "tscBatchWrite.h"
#include "tscBatchWrite.h"
#include "tscLog.h"
#include "tscSubquery.h"
#include "tscSubquery.h"
#include "tsclient.h"
#include "tsclient.h"
#include "tscLog.h"
/**
/**
* Represents the callback function and its context.
* Represents the callback function and its context.
...
@@ -57,9 +57,7 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
...
@@ -57,9 +57,7 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
}
}
pSql
->
res
.
code
=
code
;
pSql
->
res
.
code
=
code
;
if
(
pSql
->
fp
)
{
tscAsyncResultOnError
(
pSql
);
pSql
->
fp
(
pSql
->
param
,
pSql
,
code
);
}
}
}
/**
/**
...
@@ -70,8 +68,8 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
...
@@ -70,8 +68,8 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
* @param code the error code.
* @param code the error code.
*/
*/
static
void
batchResultCallback
(
void
*
param
,
TAOS_RES
*
tres
,
int32_t
code
)
{
static
void
batchResultCallback
(
void
*
param
,
TAOS_RES
*
tres
,
int32_t
code
)
{
SBatchCallbackContext
*
context
=
param
;
SBatchCallbackContext
*
context
=
param
;
SSqlObj
*
res
=
tres
;
SSqlObj
*
res
=
tres
;
// handle corner case [context == null].
// handle corner case [context == null].
if
(
context
==
NULL
)
{
if
(
context
==
NULL
)
{
...
@@ -104,47 +102,47 @@ static void batchResultCallback(void* param, TAOS_RES* tres, int32_t code) {
...
@@ -104,47 +102,47 @@ static void batchResultCallback(void* param, TAOS_RES* tres, int32_t code) {
free
(
context
);
free
(
context
);
}
}
int32_t
dispatcherBatchBuilder
(
S
SqlObj
**
polls
,
size_t
nPolls
,
SSqlObj
**
batch
)
{
int32_t
dispatcherBatchBuilder
(
S
BatchRequest
*
pRequest
,
SSqlObj
**
batch
)
{
if
(
!
polls
||
!
nPolls
)
{
assert
(
pRequest
);
return
TSDB_CODE_SUCCESS
;
assert
(
pRequest
->
pRequests
)
;
}
assert
(
pRequest
->
nRequests
);
// create the callback context.
// create the callback context.
SBatchCallbackContext
*
context
=
calloc
(
1
,
sizeof
(
SBatchCallbackContext
)
+
nPolls
*
sizeof
(
SCallbackHandler
));
SBatchCallbackContext
*
context
=
calloc
(
1
,
sizeof
(
SBatchCallbackContext
)
+
pRequest
->
nRequests
*
sizeof
(
SCallbackHandler
));
if
(
context
==
NULL
)
{
if
(
context
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
tscDebug
(
"create batch call back context: %p"
,
context
);
tscDebug
(
"create batch call back context: %p"
,
context
);
// initialize the callback context.
// initialize the callback context.
context
->
nHandlers
=
nPoll
s
;
context
->
nHandlers
=
pRequest
->
nRequest
s
;
for
(
size_t
i
=
0
;
i
<
nPoll
s
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
pRequest
->
nRequest
s
;
++
i
)
{
SSqlObj
*
pSql
=
p
oll
s
[
i
];
SSqlObj
*
pSql
=
p
Request
->
pRequest
s
[
i
];
context
->
handler
[
i
].
fp
=
pSql
->
fp
;
context
->
handler
[
i
].
fp
=
pSql
->
fp
;
context
->
handler
[
i
].
param
=
pSql
->
param
;
context
->
handler
[
i
].
param
=
pSql
->
param
;
}
}
// merge the statements into single one.
// merge the statements into single one.
tscDebug
(
"start to merge %zu sql objs"
,
nPoll
s
);
tscDebug
(
"start to merge %zu sql objs"
,
pRequest
->
nRequest
s
);
SSqlObj
*
pFirst
=
poll
s
[
0
];
SSqlObj
*
pFirst
=
pRequest
->
pRequest
s
[
0
];
int32_t
code
=
tscMergeSSqlObjs
(
polls
,
nPoll
s
,
pFirst
);
int32_t
code
=
tscMergeSSqlObjs
(
pRequest
->
pRequests
,
pRequest
->
nRequest
s
,
pFirst
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
const
char
*
msg
=
tstrerror
(
code
);
const
char
*
msg
=
tstrerror
(
code
);
tscDebug
(
"failed to merge sql objects: %s"
,
msg
);
tscDebug
(
"failed to merge sql objects: %s"
,
msg
);
free
(
context
);
free
(
context
);
taosReleaseRef
(
tscObjRef
,
pFirst
->
self
);
return
code
;
return
code
;
}
}
pFirst
->
fp
=
batchResultCallback
;
pFirst
->
fp
=
batchResultCallback
;
pFirst
->
param
=
context
;
pFirst
->
param
=
context
;
pFirst
->
fetchFp
=
pFirst
->
fp
;
pFirst
->
fetchFp
=
pFirst
->
fp
;
taosAcquireRef
(
tscObjRef
,
pFirst
->
self
);
*
batch
=
pFirst
;
*
batch
=
pFirst
;
for
(
int
i
=
1
;
i
<
nPoll
s
;
++
i
)
{
for
(
int
i
=
0
;
i
<
pRequest
->
nRequest
s
;
++
i
)
{
SSqlObj
*
pSql
=
poll
s
[
i
];
SSqlObj
*
pSql
=
pRequest
->
pRequest
s
[
i
];
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
}
}
return
code
;
return
code
;
...
@@ -158,40 +156,37 @@ int32_t dispatcherBatchBuilder(SSqlObj** polls, size_t nPolls, SSqlObj** batch)
...
@@ -158,40 +156,37 @@ int32_t dispatcherBatchBuilder(SSqlObj** polls, size_t nPolls, SSqlObj** batch)
* @param nPolls the number of polled SSqlObj*.
* @param nPolls the number of polled SSqlObj*.
* @return all the SSqlObj* in the buffer.
* @return all the SSqlObj* in the buffer.
*/
*/
inline
static
S
SqlObj
**
dispatcherPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
size_t
*
nPolls
)
{
inline
static
S
BatchRequest
*
dispatcherPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
)
{
if
(
!
dispatcher
->
bufferSize
)
{
if
(
!
dispatcher
->
bufferSize
)
{
*
nPolls
=
0
;
return
NULL
;
return
NULL
;
}
}
S
SqlObj
**
clone
=
malloc
(
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
S
BatchRequest
*
pRequest
=
malloc
(
sizeof
(
SBatchRequest
)
+
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
if
(
clone
==
NULL
)
{
if
(
pRequest
==
NULL
)
{
tscError
(
"failed to poll all items: out of memory"
);
tscError
(
"failed to poll all items: out of memory"
);
*
nPolls
=
0
;
return
NULL
;
return
NULL
;
}
}
memcpy
(
clone
,
dispatcher
->
buffer
,
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
*
nPolls
=
dispatcher
->
bufferSize
;
memcpy
(
pRequest
->
pRequests
,
dispatcher
->
buffer
,
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
pRequest
->
nRequests
=
dispatcher
->
bufferSize
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
bufferSize
=
0
;
dispatcher
->
bufferSize
=
0
;
return
clone
;
return
pRequest
;
}
}
/**
/**
* Poll all the SSqlObj* in the dispatcher's buffer.
* Poll all the SSqlObj* in the dispatcher's buffer.
*
*
* @param dispatcher the dispatcher.
* @param dispatcher the dispatcher.
* @param nPolls the number of polled SSqlObj*.
* @return all the SSqlObj* in the buffer.
* @return all the SSqlObj* in the buffer.
*/
*/
inline
static
S
SqlObj
**
dispatcherLockPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
size_t
*
nPolls
)
{
inline
static
S
BatchRequest
*
dispatcherLockPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
)
{
S
SqlObj
**
polls
=
NULL
;
S
BatchRequest
*
pRequest
=
NULL
;
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
p
olls
=
dispatcherPollAll
(
dispatcher
,
nPolls
);
p
Request
=
dispatcherPollAll
(
dispatcher
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
return
p
olls
;
return
p
Request
;
}
}
/**
/**
...
@@ -203,14 +198,14 @@ inline static SSqlObj** dispatcherLockPollAll(SAsyncBatchWriteDispatcher* dispat
...
@@ -203,14 +198,14 @@ inline static SSqlObj** dispatcherLockPollAll(SAsyncBatchWriteDispatcher* dispat
*/
*/
inline
static
bool
dispatcherTryOffer
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
inline
static
bool
dispatcherTryOffer
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
// if dispatcher is shutdown, must fail back to normal insertion.
// if dispatcher is shutdown, must fail back to normal insertion.
// usually not happen, unless taos_query_a(...) after taos_close(...).
// usually not happen, unless taos_query_a(...) after taos_close(...).
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
return
false
;
return
false
;
}
}
// the buffer is full.
// the buffer is full.
while
(
dispatcher
->
currentSize
>=
dispatcher
->
batchSize
)
{
while
(
dispatcher
->
currentSize
>=
dispatcher
->
batchSize
)
{
if
(
pthread_cond_wait
(
&
dispatcher
->
notFull
,
&
dispatcher
->
bufferMutex
))
{
if
(
pthread_cond_wait
(
&
dispatcher
->
notFull
,
&
dispatcher
->
bufferMutex
))
{
...
@@ -222,48 +217,49 @@ inline static bool dispatcherTryOffer(SAsyncBatchWriteDispatcher* dispatcher, SS
...
@@ -222,48 +217,49 @@ inline static bool dispatcherTryOffer(SAsyncBatchWriteDispatcher* dispatcher, SS
dispatcher
->
buffer
[
dispatcher
->
bufferSize
++
]
=
pSql
;
dispatcher
->
buffer
[
dispatcher
->
bufferSize
++
]
=
pSql
;
dispatcher
->
currentSize
+=
statementGetInsertionRows
(
pSql
);
dispatcher
->
currentSize
+=
statementGetInsertionRows
(
pSql
);
tscDebug
(
"sql obj %p has been write to insert buffer"
,
pSql
);
tscDebug
(
"sql obj %p has been write to insert buffer"
,
pSql
);
if
(
dispatcher
->
currentSize
<
dispatcher
->
batchSize
)
{
if
(
dispatcher
->
currentSize
<
dispatcher
->
batchSize
)
{
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
return
true
;
return
true
;
}
}
// the dispatcher reaches batch size.
// the dispatcher reaches batch size.
size_t
nPolls
=
0
;
SBatchRequest
*
pRequest
=
dispatcherPollAll
(
dispatcher
);
SSqlObj
**
polls
=
dispatcherPollAll
(
dispatcher
,
&
nPolls
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
if
(
polls
)
{
if
(
pRequest
)
{
dispatcherExecute
(
polls
,
nPolls
);
dispatcherAsyncExecute
(
pRequest
);
free
(
polls
);
}
}
return
true
;
return
true
;
}
}
void
dispatcherExecute
(
S
SqlObj
**
polls
,
size_t
nPolls
)
{
void
dispatcherExecute
(
S
BatchRequest
*
pRequest
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
// no item in the buffer (items has been taken by other threads).
// no item in the buffer (items has been taken by other threads).
if
(
!
p
olls
||
!
nPolls
)
{
if
(
!
p
Request
)
{
return
;
return
;
}
}
assert
(
pRequest
->
pRequests
);
assert
(
pRequest
->
nRequests
);
// merge the statements into single one.
// merge the statements into single one.
SSqlObj
*
merged
=
NULL
;
SSqlObj
*
pSql
=
NULL
;
code
=
dispatcherBatchBuilder
(
p
olls
,
nPolls
,
&
merged
);
code
=
dispatcherBatchBuilder
(
p
Request
,
&
pSql
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
goto
_error
;
}
}
tscDebug
(
"merging %zu sql objs into %p"
,
nPolls
,
merged
);
tscDebug
(
"merging %zu sql objs into %p"
,
pRequest
->
nRequests
,
pSql
);
tscHandleMultivnodeInsert
(
merged
);
tscHandleMultivnodeInsert
(
pSql
);
return
;
return
;
_error:
_error:
tscError
(
"send async batch sql obj failed, reason: %s"
,
tstrerror
(
code
));
tscError
(
"send async batch sql obj failed, reason: %s"
,
tstrerror
(
code
));
// handling the failures.
// handling the failures.
for
(
size_t
i
=
0
;
i
<
nPoll
s
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
pRequest
->
nRequest
s
;
++
i
)
{
SSqlObj
*
item
=
p
oll
s
[
i
];
SSqlObj
*
item
=
p
Request
->
pRequest
s
[
i
];
tscReturnsError
(
item
,
code
);
tscReturnsError
(
item
,
code
);
}
}
}
}
...
@@ -275,7 +271,7 @@ _error:
...
@@ -275,7 +271,7 @@ _error:
* @param millis the duration in milliseconds.
* @param millis the duration in milliseconds.
* @return the timespec after `millis` ms.
* @return the timespec after `millis` ms.
*/
*/
static
inline
void
afterMillis
(
struct
timespec
*
t
,
int32_t
millis
)
{
static
inline
void
afterMillis
(
struct
timespec
*
t
,
int32_t
millis
)
{
t
->
tv_nsec
+=
millis
*
1000000L
;
t
->
tv_nsec
+=
millis
*
1000000L
;
t
->
tv_sec
+=
t
->
tv_nsec
/
1000000000L
;
t
->
tv_sec
+=
t
->
tv_nsec
/
1000000000L
;
t
->
tv_nsec
%=
1000000000L
;
t
->
tv_nsec
%=
1000000000L
;
...
@@ -283,7 +279,7 @@ static inline void afterMillis(struct timespec *t, int32_t millis) {
...
@@ -283,7 +279,7 @@ static inline void afterMillis(struct timespec *t, int32_t millis) {
/**
/**
* Sleep until `timeout` timespec. When dispatcherShutdown(...) called, the function will return immediately.
* Sleep until `timeout` timespec. When dispatcherShutdown(...) called, the function will return immediately.
*
*
* @param dispatcher the dispatcher thread to sleep.
* @param dispatcher the dispatcher thread to sleep.
* @param timeout the timeout in CLOCK_REALTIME.
* @param timeout the timeout in CLOCK_REALTIME.
*/
*/
...
@@ -313,15 +309,12 @@ static void* timeoutManagerCallback(void* arg) {
...
@@ -313,15 +309,12 @@ static void* timeoutManagerCallback(void* arg) {
struct
timespec
timeout
;
struct
timespec
timeout
;
clock_gettime
(
CLOCK_REALTIME
,
&
timeout
);
clock_gettime
(
CLOCK_REALTIME
,
&
timeout
);
afterMillis
(
&
timeout
,
manager
->
timeoutMs
);
afterMillis
(
&
timeout
,
manager
->
timeoutMs
);
size_t
nPolls
=
0
;
SBatchRequest
*
pRequest
=
dispatcherLockPollAll
(
manager
->
dispatcher
);
SSqlObj
**
polls
=
dispatcherLockPollAll
(
manager
->
dispatcher
,
&
nPolls
);
if
(
pRequest
)
{
dispatcherAsyncExecute
(
pRequest
);
if
(
polls
)
{
dispatcherExecute
(
polls
,
nPolls
);
free
(
polls
);
}
}
// Similar to scheduleAtFixedRate in Java, if the execution time exceed
// Similar to scheduleAtFixedRate in Java, if the execution time exceed
// `timeoutMs` milliseconds, then there will be no sleep.
// `timeoutMs` milliseconds, then there will be no sleep.
timeoutManagerSleepUntil
(
manager
,
&
timeout
);
timeoutManagerSleepUntil
(
manager
,
&
timeout
);
...
@@ -336,13 +329,13 @@ SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, i
...
@@ -336,13 +329,13 @@ SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, i
}
}
assert
(
pClient
!=
NULL
);
assert
(
pClient
!=
NULL
);
dispatcher
->
pClient
=
pClient
;
dispatcher
->
pClient
=
pClient
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
bufferSize
=
0
;
dispatcher
->
bufferSize
=
0
;
dispatcher
->
batchSize
=
batchSize
;
dispatcher
->
batchSize
=
batchSize
;
atomic_store_8
(
&
dispatcher
->
shutdown
,
false
);
atomic_store_8
(
&
dispatcher
->
shutdown
,
false
);
// init the mutex and the cond.
// init the mutex and the cond.
pthread_mutex_init
(
&
dispatcher
->
bufferMutex
,
NULL
);
pthread_mutex_init
(
&
dispatcher
->
bufferMutex
,
NULL
);
pthread_cond_init
(
&
dispatcher
->
notFull
,
NULL
);
pthread_cond_init
(
&
dispatcher
->
notFull
,
NULL
);
...
@@ -361,7 +354,7 @@ SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, i
...
@@ -361,7 +354,7 @@ SAsyncBatchWriteDispatcher* createSAsyncBatchWriteDispatcher(STscObj* pClient, i
/**
/**
* Shutdown the dispatcher and join the timeout thread.
* Shutdown the dispatcher and join the timeout thread.
*
*
* @param dispatcher the dispatcher.
* @param dispatcher the dispatcher.
*/
*/
inline
static
void
dispatcherShutdown
(
SAsyncBatchWriteDispatcher
*
dispatcher
)
{
inline
static
void
dispatcherShutdown
(
SAsyncBatchWriteDispatcher
*
dispatcher
)
{
...
@@ -380,21 +373,20 @@ void destroySAsyncBatchWriteDispatcher(SAsyncBatchWriteDispatcher* dispatcher) {
...
@@ -380,21 +373,20 @@ void destroySAsyncBatchWriteDispatcher(SAsyncBatchWriteDispatcher* dispatcher) {
// poll and send all the statements in the buffer.
// poll and send all the statements in the buffer.
while
(
true
)
{
while
(
true
)
{
size_t
nPolls
=
0
;
SBatchRequest
*
pRequest
=
dispatcherLockPollAll
(
dispatcher
);
SSqlObj
**
polls
=
dispatcherLockPollAll
(
dispatcher
,
&
nPolls
);
if
(
!
pRequest
)
{
if
(
!
polls
)
{
break
;
break
;
}
}
dispatcherExecute
(
p
olls
,
nPolls
);
dispatcherExecute
(
p
Request
);
free
(
p
olls
);
free
(
p
Request
);
}
}
// destroy the timeout manager.
// destroy the timeout manager.
destroySDispatcherTimeoutManager
(
dispatcher
->
timeoutManager
);
destroySDispatcherTimeoutManager
(
dispatcher
->
timeoutManager
);
// destroy the mutex.
// destroy the mutex.
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
free
(
dispatcher
);
free
(
dispatcher
);
}
}
...
@@ -422,12 +414,12 @@ bool dispatcherCanDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql
...
@@ -422,12 +414,12 @@ bool dispatcherCanDispatch(SAsyncBatchWriteDispatcher* dispatcher, SSqlObj* pSql
if
(
pInsertParam
->
payloadType
!=
PAYLOAD_TYPE_KV
)
{
if
(
pInsertParam
->
payloadType
!=
PAYLOAD_TYPE_KV
)
{
return
false
;
return
false
;
}
}
// no schema attached.
// no schema attached.
if
(
pInsertParam
->
schemaAttached
)
{
if
(
pInsertParam
->
schemaAttached
)
{
return
false
;
return
false
;
}
}
// too many insertion rows, fail back to normal insertion.
// too many insertion rows, fail back to normal insertion.
if
(
statementGetInsertionRows
(
pSql
)
>=
dispatcher
->
batchSize
)
{
if
(
statementGetInsertionRows
(
pSql
)
>=
dispatcher
->
batchSize
)
{
return
false
;
return
false
;
...
@@ -463,14 +455,15 @@ static void destroyDispatcher(void* arg) {
...
@@ -463,14 +455,15 @@ static void destroyDispatcher(void* arg) {
destroySAsyncBatchWriteDispatcher
(
dispatcher
);
destroySAsyncBatchWriteDispatcher
(
dispatcher
);
}
}
SDispatcherManager
*
createDispatcherManager
(
STscObj
*
pClient
,
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
SDispatcherManager
*
createDispatcherManager
(
STscObj
*
pClient
,
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
SDispatcherManager
*
dispatcher
=
calloc
(
1
,
sizeof
(
SDispatcherManager
));
SDispatcherManager
*
dispatcher
=
calloc
(
1
,
sizeof
(
SDispatcherManager
));
if
(
!
dispatcher
)
{
if
(
!
dispatcher
)
{
return
NULL
;
return
NULL
;
}
}
assert
(
pClient
!=
NULL
);
assert
(
pClient
!=
NULL
);
dispatcher
->
pClient
=
pClient
;
dispatcher
->
pClient
=
pClient
;
dispatcher
->
batchSize
=
batchSize
;
dispatcher
->
batchSize
=
batchSize
;
dispatcher
->
timeoutMs
=
timeoutMs
;
dispatcher
->
timeoutMs
=
timeoutMs
;
...
@@ -515,7 +508,7 @@ void destroyDispatcherManager(SDispatcherManager* manager) {
...
@@ -515,7 +508,7 @@ void destroyDispatcherManager(SDispatcherManager* manager) {
if
(
manager
->
isThreadLocal
)
{
if
(
manager
->
isThreadLocal
)
{
pthread_key_delete
(
manager
->
key
);
pthread_key_delete
(
manager
->
key
);
}
}
if
(
manager
->
pGlobal
)
{
if
(
manager
->
pGlobal
)
{
destroySAsyncBatchWriteDispatcher
(
manager
->
pGlobal
);
destroySAsyncBatchWriteDispatcher
(
manager
->
pGlobal
);
}
}
...
@@ -528,14 +521,14 @@ SDispatcherTimeoutManager* createSDispatcherTimeoutManager(SAsyncBatchWriteDispa
...
@@ -528,14 +521,14 @@ SDispatcherTimeoutManager* createSDispatcherTimeoutManager(SAsyncBatchWriteDispa
if
(
!
manager
)
{
if
(
!
manager
)
{
return
NULL
;
return
NULL
;
}
}
manager
->
timeoutMs
=
timeoutMs
;
manager
->
timeoutMs
=
timeoutMs
;
manager
->
dispatcher
=
dispatcher
;
manager
->
dispatcher
=
dispatcher
;
atomic_store_8
(
&
manager
->
shutdown
,
false
);
atomic_store_8
(
&
manager
->
shutdown
,
false
);
pthread_mutex_init
(
&
manager
->
sleepMutex
,
NULL
);
pthread_mutex_init
(
&
manager
->
sleepMutex
,
NULL
);
pthread_cond_init
(
&
manager
->
timeout
,
NULL
);
pthread_cond_init
(
&
manager
->
timeout
,
NULL
);
// init background thread.
// init background thread.
if
(
pthread_create
(
&
manager
->
background
,
NULL
,
timeoutManagerCallback
,
manager
))
{
if
(
pthread_create
(
&
manager
->
background
,
NULL
,
timeoutManagerCallback
,
manager
))
{
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
...
@@ -553,7 +546,7 @@ void destroySDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
...
@@ -553,7 +546,7 @@ void destroySDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
shutdownSDispatcherTimeoutManager
(
manager
);
shutdownSDispatcherTimeoutManager
(
manager
);
manager
->
dispatcher
->
timeoutManager
=
NULL
;
manager
->
dispatcher
->
timeoutManager
=
NULL
;
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
pthread_cond_destroy
(
&
manager
->
timeout
);
pthread_cond_destroy
(
&
manager
->
timeout
);
free
(
manager
);
free
(
manager
);
...
@@ -576,3 +569,35 @@ bool isShutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
...
@@ -576,3 +569,35 @@ bool isShutdownSDispatcherTimeoutManager(SDispatcherTimeoutManager* manager) {
}
}
return
atomic_load_8
(
&
manager
->
shutdown
);
return
atomic_load_8
(
&
manager
->
shutdown
);
}
}
/**
* The proxy function to call `dispatcherExecute`.
*
* @param pMsg the schedule message.
*/
static
void
dispatcherExecuteProxy
(
struct
SSchedMsg
*
pMsg
)
{
SBatchRequest
*
pRequest
=
pMsg
->
ahandle
;
if
(
!
pRequest
)
{
return
;
}
pMsg
->
ahandle
=
NULL
;
dispatcherExecute
(
pRequest
);
free
(
pRequest
);
}
void
dispatcherAsyncExecute
(
SBatchRequest
*
pRequest
)
{
if
(
!
pRequest
)
{
return
;
}
assert
(
pRequest
->
pRequests
);
assert
(
pRequest
->
nRequests
);
SSchedMsg
schedMsg
=
{
0
};
schedMsg
.
fp
=
dispatcherExecuteProxy
;
schedMsg
.
ahandle
=
(
void
*
)
pRequest
;
schedMsg
.
thandle
=
(
void
*
)
1
;
schedMsg
.
msg
=
0
;
taosScheduleTask
(
tscQhandle
,
&
schedMsg
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录