Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
28a80be7
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
28a80be7
编写于
4月 18, 2023
作者:
D
dapan1121
提交者:
GitHub
4月 18, 2023
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #20928 from taosdata/szhou/replace-function-2
enhance: udf handle expired after 10s
上级
76c628c8
a2d75a32
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
87 addition
and
35 deletion
+87
-35
source/libs/function/src/tudf.c
source/libs/function/src/tudf.c
+84
-34
source/libs/function/src/udfd.c
source/libs/function/src/udfd.c
+3
-1
未找到文件。
source/libs/function/src/tudf.c
浏览文件 @
28a80be7
...
...
@@ -343,7 +343,7 @@ typedef struct SUdfcFuncStub {
char
udfName
[
TSDB_FUNC_NAME_LEN
+
1
];
UdfcFuncHandle
handle
;
int32_t
refCount
;
int64_t
lastRef
Time
;
int64_t
create
Time
;
}
SUdfcFuncStub
;
typedef
struct
SUdfcProxy
{
...
...
@@ -363,6 +363,7 @@ typedef struct SUdfcProxy {
uv_mutex_t
udfStubsMutex
;
SArray
*
udfStubs
;
// SUdfcFuncStub
SArray
*
expiredUdfStubs
;
//SUdfcFuncStub
uv_mutex_t
udfcUvMutex
;
int8_t
initialized
;
...
...
@@ -959,7 +960,7 @@ int32_t udfcOpen();
int32_t
udfcClose
();
int32_t
acquireUdfFuncHandle
(
char
*
udfName
,
UdfcFuncHandle
*
pHandle
);
void
releaseUdfFuncHandle
(
char
*
udfName
);
void
releaseUdfFuncHandle
(
char
*
udfName
,
UdfcFuncHandle
handle
);
int32_t
cleanUpUdfs
();
bool
udfAggGetEnv
(
struct
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
);
...
...
@@ -967,6 +968,8 @@ bool udfAggInit(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo *pRes
int32_t
udfAggProcess
(
struct
SqlFunctionCtx
*
pCtx
);
int32_t
udfAggFinalize
(
struct
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
);
void
cleanupNotExpiredUdfs
();
void
cleanupExpiredUdfs
();
int
compareUdfcFuncSub
(
const
void
*
elem1
,
const
void
*
elem2
)
{
SUdfcFuncStub
*
stub1
=
(
SUdfcFuncStub
*
)
elem1
;
SUdfcFuncStub
*
stub2
=
(
SUdfcFuncStub
*
)
elem2
;
...
...
@@ -982,16 +985,24 @@ int32_t acquireUdfFuncHandle(char *udfName, UdfcFuncHandle *pHandle) {
if
(
stubIndex
!=
-
1
)
{
SUdfcFuncStub
*
foundStub
=
taosArrayGet
(
gUdfcProxy
.
udfStubs
,
stubIndex
);
UdfcFuncHandle
handle
=
foundStub
->
handle
;
if
(
handle
!=
NULL
&&
((
SUdfcUvSession
*
)
handle
)
->
udfUvPipe
!=
NULL
)
{
*
pHandle
=
foundStub
->
handle
;
++
foundStub
->
refCount
;
foundStub
->
lastRefTime
=
taosGetTimestampUs
();
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
0
;
int64_t
currUs
=
taosGetTimestampUs
();
bool
expired
=
(
currUs
-
foundStub
->
createTime
)
>=
10
*
1000
*
1000
;
if
(
!
expired
)
{
if
(
handle
!=
NULL
&&
((
SUdfcUvSession
*
)
handle
)
->
udfUvPipe
!=
NULL
)
{
*
pHandle
=
foundStub
->
handle
;
++
foundStub
->
refCount
;
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
0
;
}
else
{
fnInfo
(
"udf invalid handle for %s, refCount: %d, create time: %"
PRId64
". remove it from cache"
,
udfName
,
foundStub
->
refCount
,
foundStub
->
createTime
);
taosArrayRemove
(
gUdfcProxy
.
udfStubs
,
stubIndex
);
}
}
else
{
fnInfo
(
"invalid handle for %s, refCount: %d, last ref time: %"
PRId64
". remove it from cache"
,
udfName
,
foundStub
->
refCount
,
foundStub
->
lastRefTime
);
fnInfo
(
"udf handle expired for %s, will setup udf. move it to expired list"
,
udfName
);
taosArrayRemove
(
gUdfcProxy
.
udfStubs
,
stubIndex
);
taosArrayPush
(
gUdfcProxy
.
expiredUdfStubs
,
foundStub
);
taosArraySort
(
gUdfcProxy
.
expiredUdfStubs
,
compareUdfcFuncSub
);
}
}
*
pHandle
=
NULL
;
...
...
@@ -1001,7 +1012,7 @@ int32_t acquireUdfFuncHandle(char *udfName, UdfcFuncHandle *pHandle) {
strncpy
(
stub
.
udfName
,
udfName
,
TSDB_FUNC_NAME_LEN
);
stub
.
handle
=
*
pHandle
;
++
stub
.
refCount
;
stub
.
lastRef
Time
=
taosGetTimestampUs
();
stub
.
create
Time
=
taosGetTimestampUs
();
taosArrayPush
(
gUdfcProxy
.
udfStubs
,
&
stub
);
taosArraySort
(
gUdfcProxy
.
udfStubs
,
compareUdfcFuncSub
);
}
else
{
...
...
@@ -1012,32 +1023,51 @@ int32_t acquireUdfFuncHandle(char *udfName, UdfcFuncHandle *pHandle) {
return
code
;
}
void
releaseUdfFuncHandle
(
char
*
udfName
)
{
void
releaseUdfFuncHandle
(
char
*
udfName
,
UdfcFuncHandle
handle
)
{
uv_mutex_lock
(
&
gUdfcProxy
.
udfStubsMutex
);
SUdfcFuncStub
key
=
{
0
};
strncpy
(
key
.
udfName
,
udfName
,
TSDB_FUNC_NAME_LEN
);
SUdfcFuncStub
*
foundStub
=
taosArraySearch
(
gUdfcProxy
.
udfStubs
,
&
key
,
compareUdfcFuncSub
,
TD_EQ
);
if
(
!
foundStub
)
{
SUdfcFuncStub
*
expiredStub
=
taosArraySearch
(
gUdfcProxy
.
expiredUdfStubs
,
&
key
,
compareUdfcFuncSub
,
TD_EQ
);
if
(
!
foundStub
&&
!
expiredStub
)
{
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
;
}
if
(
foundStub
->
refCount
>
0
)
{
if
(
foundStub
!=
NULL
&&
foundStub
->
handle
==
handle
&&
foundStub
->
refCount
>
0
)
{
--
foundStub
->
refCount
;
}
if
(
expiredStub
!=
NULL
&&
expiredStub
->
handle
==
handle
&&
expiredStub
->
refCount
>
0
)
{
--
expiredStub
->
refCount
;
}
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
}
int32_t
cleanUpUdfs
()
{
int8_t
initialized
=
atomic_load_8
(
&
gUdfcProxy
.
initialized
);
if
(
!
initialized
)
{
return
TSDB_CODE_SUCCESS
;
void
cleanupExpiredUdfs
()
{
int32_t
i
=
0
;
SArray
*
expiredUdfStubs
=
taosArrayInit
(
16
,
sizeof
(
SUdfcFuncStub
));
while
(
i
<
taosArrayGetSize
(
gUdfcProxy
.
expiredUdfStubs
))
{
SUdfcFuncStub
*
stub
=
taosArrayGet
(
gUdfcProxy
.
expiredUdfStubs
,
i
);
if
(
stub
->
refCount
==
0
)
{
fnInfo
(
"tear down udf. expired. udf name: %s, handle: %p, ref count: %d"
,
stub
->
udfName
,
stub
->
handle
,
stub
->
refCount
);
doTeardownUdf
(
stub
->
handle
);
}
else
{
fnInfo
(
"udf still in use. expired. udf name: %s, ref count: %d, create time: %"
PRId64
", handle: %p"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
createTime
,
stub
->
handle
);
UdfcFuncHandle
handle
=
stub
->
handle
;
if
(
handle
!=
NULL
&&
((
SUdfcUvSession
*
)
handle
)
->
udfUvPipe
!=
NULL
)
{
taosArrayPush
(
expiredUdfStubs
,
stub
);
}
else
{
fnInfo
(
"udf invalid handle for %s, expired. refCount: %d, create time: %"
PRId64
". remove it from cache"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
createTime
);
}
}
++
i
;
}
taosArrayDestroy
(
gUdfcProxy
.
expiredUdfStubs
);
gUdfcProxy
.
expiredUdfStubs
=
expiredUdfStubs
;
}
uv_mutex_lock
(
&
gUdfcProxy
.
udfStubsMutex
);
if
(
gUdfcProxy
.
udfStubs
==
NULL
||
taosArrayGetSize
(
gUdfcProxy
.
udfStubs
)
==
0
)
{
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
TSDB_CODE_SUCCESS
;
}
void
cleanupNotExpiredUdfs
()
{
SArray
*
udfStubs
=
taosArrayInit
(
16
,
sizeof
(
SUdfcFuncStub
));
int32_t
i
=
0
;
while
(
i
<
taosArrayGetSize
(
gUdfcProxy
.
udfStubs
))
{
...
...
@@ -1046,20 +1076,38 @@ int32_t cleanUpUdfs() {
fnInfo
(
"tear down udf. udf name: %s, handle: %p, ref count: %d"
,
stub
->
udfName
,
stub
->
handle
,
stub
->
refCount
);
doTeardownUdf
(
stub
->
handle
);
}
else
{
fnInfo
(
"udf still in use. udf name: %s, ref count: %d,
last ref
time: %"
PRId64
", handle: %p"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
lastRef
Time
,
stub
->
handle
);
fnInfo
(
"udf still in use. udf name: %s, ref count: %d,
create
time: %"
PRId64
", handle: %p"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
create
Time
,
stub
->
handle
);
UdfcFuncHandle
handle
=
stub
->
handle
;
if
(
handle
!=
NULL
&&
((
SUdfcUvSession
*
)
handle
)
->
udfUvPipe
!=
NULL
)
{
taosArrayPush
(
udfStubs
,
stub
);
}
else
{
fnInfo
(
"udf invalid handle for %s, refCount: %d,
last ref
time: %"
PRId64
". remove it from cache"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
lastRef
Time
);
fnInfo
(
"udf invalid handle for %s, refCount: %d,
create
time: %"
PRId64
". remove it from cache"
,
stub
->
udfName
,
stub
->
refCount
,
stub
->
create
Time
);
}
}
++
i
;
}
taosArrayDestroy
(
gUdfcProxy
.
udfStubs
);
gUdfcProxy
.
udfStubs
=
udfStubs
;
}
int32_t
cleanUpUdfs
()
{
int8_t
initialized
=
atomic_load_8
(
&
gUdfcProxy
.
initialized
);
if
(
!
initialized
)
{
return
TSDB_CODE_SUCCESS
;
}
uv_mutex_lock
(
&
gUdfcProxy
.
udfStubsMutex
);
if
((
gUdfcProxy
.
udfStubs
==
NULL
||
taosArrayGetSize
(
gUdfcProxy
.
udfStubs
)
==
0
)
&&
(
gUdfcProxy
.
expiredUdfStubs
==
NULL
||
taosArrayGetSize
(
gUdfcProxy
.
expiredUdfStubs
)
==
0
))
{
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
TSDB_CODE_SUCCESS
;
}
cleanupNotExpiredUdfs
();
cleanupExpiredUdfs
();
uv_mutex_unlock
(
&
gUdfcProxy
.
udfStubsMutex
);
return
0
;
}
...
...
@@ -1075,7 +1123,7 @@ int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols,
code
=
doCallUdfScalarFunc
(
handle
,
input
,
numOfCols
,
output
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
fnError
(
"udfc scalar function execution failure"
);
releaseUdfFuncHandle
(
udfName
);
releaseUdfFuncHandle
(
udfName
,
handle
);
return
code
;
}
...
...
@@ -1089,7 +1137,7 @@ int32_t callUdfScalarFunc(char *udfName, SScalarParam *input, int32_t numOfCols,
code
=
TSDB_CODE_UDF_INVALID_OUTPUT_TYPE
;
}
}
releaseUdfFuncHandle
(
udfName
);
releaseUdfFuncHandle
(
udfName
,
handle
);
return
code
;
}
...
...
@@ -1122,7 +1170,7 @@ bool udfAggInit(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo *pResult
SUdfInterBuf
buf
=
{
0
};
if
((
udfCode
=
doCallUdfAggInit
(
handle
,
&
buf
))
!=
0
)
{
fnError
(
"udfAggInit error. step doCallUdfAggInit. udf code: %d"
,
udfCode
);
releaseUdfFuncHandle
(
pCtx
->
udfName
);
releaseUdfFuncHandle
(
pCtx
->
udfName
,
handle
);
return
false
;
}
if
(
buf
.
bufLen
<=
session
->
bufSize
)
{
...
...
@@ -1131,10 +1179,10 @@ bool udfAggInit(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo *pResult
udfRes
->
interResNum
=
buf
.
numOfResult
;
}
else
{
fnError
(
"udfc inter buf size %d is greater than function bufSize %d"
,
buf
.
bufLen
,
session
->
bufSize
);
releaseUdfFuncHandle
(
pCtx
->
udfName
);
releaseUdfFuncHandle
(
pCtx
->
udfName
,
handle
);
return
false
;
}
releaseUdfFuncHandle
(
pCtx
->
udfName
);
releaseUdfFuncHandle
(
pCtx
->
udfName
,
handle
);
freeUdfInterBuf
(
&
buf
);
return
true
;
}
...
...
@@ -1191,7 +1239,7 @@ int32_t udfAggProcess(struct SqlFunctionCtx *pCtx) {
taosArrayDestroy
(
pTempBlock
->
pDataBlock
);
taosMemoryFree
(
pTempBlock
);
releaseUdfFuncHandle
(
pCtx
->
udfName
);
releaseUdfFuncHandle
(
pCtx
->
udfName
,
handle
);
freeUdfInterBuf
(
&
newState
);
return
udfCode
;
}
...
...
@@ -1236,7 +1284,7 @@ int32_t udfAggFinalize(struct SqlFunctionCtx *pCtx, SSDataBlock *pBlock) {
freeUdfInterBuf
(
&
resultBuf
);
int32_t
numOfResults
=
functionFinalizeWithResultBuf
(
pCtx
,
pBlock
,
udfRes
->
finalResBuf
);
releaseUdfFuncHandle
(
pCtx
->
udfName
);
releaseUdfFuncHandle
(
pCtx
->
udfName
,
handle
);
return
udfCallCode
==
0
?
numOfResults
:
udfCallCode
;
}
...
...
@@ -1663,6 +1711,7 @@ int32_t udfcOpen() {
uv_barrier_wait
(
&
proxy
->
initBarrier
);
uv_mutex_init
(
&
proxy
->
udfStubsMutex
);
proxy
->
udfStubs
=
taosArrayInit
(
8
,
sizeof
(
SUdfcFuncStub
));
proxy
->
expiredUdfStubs
=
taosArrayInit
(
8
,
sizeof
(
SUdfcFuncStub
));
uv_mutex_init
(
&
proxy
->
udfcUvMutex
);
fnInfo
(
"udfc initialized"
)
return
0
;
}
...
...
@@ -1679,6 +1728,7 @@ int32_t udfcClose() {
uv_thread_join
(
&
udfc
->
loopThread
);
uv_mutex_destroy
(
&
udfc
->
taskQueueMutex
);
uv_barrier_destroy
(
&
udfc
->
initBarrier
);
taosArrayDestroy
(
udfc
->
expiredUdfStubs
);
taosArrayDestroy
(
udfc
->
udfStubs
);
uv_mutex_destroy
(
&
udfc
->
udfStubsMutex
);
uv_mutex_destroy
(
&
udfc
->
udfcUvMutex
);
...
...
source/libs/function/src/udfd.c
浏览文件 @
28a80be7
...
...
@@ -591,7 +591,7 @@ SUdf *udfdNewUdf(const char *udfName) {
SUdf
*
udfdGetOrCreateUdf
(
const
char
*
udfName
)
{
uv_mutex_lock
(
&
global
.
udfsMutex
);
SUdf
**
pUdfHash
=
taosHashGet
(
global
.
udfsHash
,
udfName
,
strlen
(
udfName
));
int64_t
currTime
=
taosGetTimestamp
Sec
();
int64_t
currTime
=
taosGetTimestamp
Ms
();
bool
expired
=
false
;
if
(
pUdfHash
)
{
expired
=
currTime
-
(
*
pUdfHash
)
->
lastFetchTime
>
10
*
1000
;
// 10s
...
...
@@ -688,6 +688,8 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) {
output
.
colMeta
.
type
=
udf
->
outputType
;
output
.
colMeta
.
precision
=
0
;
output
.
colMeta
.
scale
=
0
;
udfColEnsureCapacity
(
&
output
,
call
->
block
.
info
.
rows
);
SUdfDataBlock
input
=
{
0
};
convertDataBlockToUdfDataBlock
(
&
call
->
block
,
&
input
);
code
=
udf
->
scriptPlugin
->
udfScalarProcFunc
(
&
input
,
&
output
,
udf
->
scriptUdfCtx
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录