2023-06-30 11:24:37 +08:00
package tools
import (
"context"
2024-04-28 11:47:05 +08:00
"fmt"
2024-08-01 16:12:41 +08:00
"os"
"time"
2024-04-19 22:23:08 +08:00
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
2024-04-28 11:47:05 +08:00
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
2024-08-01 16:12:41 +08:00
pbconversation "github.com/openimsdk/protocol/conversation"
2024-04-28 11:47:05 +08:00
"github.com/openimsdk/protocol/msg"
2024-11-29 16:59:24 +08:00
"github.com/openimsdk/protocol/third"
2024-08-01 16:12:41 +08:00
2024-04-28 11:47:05 +08:00
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/mw"
2024-12-07 17:35:42 +08:00
"github.com/openimsdk/tools/utils/runtimeenv"
2024-04-28 11:47:05 +08:00
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
2023-06-30 11:24:37 +08:00
2024-04-19 22:23:08 +08:00
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
2024-03-06 15:58:05 +08:00
"github.com/robfig/cron/v3"
2023-06-30 11:24:37 +08:00
)
2024-04-19 22:23:08 +08:00
type CronTaskConfig struct {
2024-05-14 18:21:36 +08:00
CronTask config . CronTask
Share config . Share
Discovery config . Discovery
2024-12-07 17:35:42 +08:00
runTimeEnv string
2024-04-19 22:23:08 +08:00
}
func Start ( ctx context . Context , config * CronTaskConfig ) error {
2024-12-07 17:35:42 +08:00
config . runTimeEnv = runtimeenv . PrintRuntimeEnvironment ( )
log . CInfo ( ctx , "CRON-TASK server is initializing" , "runTimeEnv" , config . runTimeEnv , "chatRecordsClearTime" , config . CronTask . CronExecuteTime , "msgDestructTime" , config . CronTask . RetainChatRecords )
2024-04-28 11:47:05 +08:00
if config . CronTask . RetainChatRecords < 1 {
return errs . New ( "msg destruct time must be greater than 1" ) . Wrap ( )
2023-11-13 15:21:54 +08:00
}
2024-12-07 17:35:42 +08:00
client , err := kdisc . NewDiscoveryRegister ( & config . Discovery , config . runTimeEnv )
2023-06-30 11:24:37 +08:00
if err != nil {
2024-04-28 11:47:05 +08:00
return errs . WrapMsg ( err , "failed to register discovery service" )
2023-07-12 15:31:24 +08:00
}
2024-04-28 11:47:05 +08:00
client . AddOption ( mw . GrpcClient ( ) , grpc . WithTransportCredentials ( insecure . NewCredentials ( ) ) )
ctx = mcontext . SetOpUserID ( ctx , config . Share . IMAdminUserID [ 0 ] )
2024-08-01 16:12:41 +08:00
2024-12-07 12:11:12 +08:00
msgConn , err := client . GetConn ( ctx , config . Discovery . RpcService . Msg )
2023-07-19 10:47:28 +08:00
if err != nil {
2024-04-28 11:47:05 +08:00
return err
2023-11-13 15:21:54 +08:00
}
2024-08-01 16:12:41 +08:00
2024-12-07 12:11:12 +08:00
thirdConn , err := client . GetConn ( ctx , config . Discovery . RpcService . Third )
2024-11-29 16:59:24 +08:00
if err != nil {
return err
}
2024-08-01 16:12:41 +08:00
2024-12-07 12:11:12 +08:00
conversationConn , err := client . GetConn ( ctx , config . Discovery . RpcService . Conversation )
2024-08-01 16:12:41 +08:00
if err != nil {
return err
}
msgClient := msg . NewMsgClient ( msgConn )
conversationClient := pbconversation . NewConversationClient ( conversationConn )
2024-11-29 16:59:24 +08:00
thirdClient := third . NewThirdClient ( thirdConn )
2024-08-01 16:12:41 +08:00
2024-04-28 11:47:05 +08:00
crontab := cron . New ( )
2024-08-01 16:12:41 +08:00
// scheduled hard delete outdated Msgs in specific time.
2024-12-03 14:12:47 +08:00
destructMsgsFunc := func ( ) {
2024-04-28 11:47:05 +08:00
now := time . Now ( )
deltime := now . Add ( - time . Hour * 24 * time . Duration ( config . CronTask . RetainChatRecords ) )
ctx := mcontext . SetOperationID ( ctx , fmt . Sprintf ( "cron_%d_%d" , os . Getpid ( ) , deltime . UnixMilli ( ) ) )
2024-12-03 14:12:47 +08:00
log . ZDebug ( ctx , "Destruct chat records" , "deltime" , deltime , "timestamp" , deltime . UnixMilli ( ) )
2024-08-14 18:20:42 +08:00
2024-12-03 14:12:47 +08:00
if _ , err := msgClient . DestructMsgs ( ctx , & msg . DestructMsgsReq { Timestamp : deltime . UnixMilli ( ) } ) ; err != nil {
log . ZError ( ctx , "cron destruct chat records failed" , err , "deltime" , deltime , "cont" , time . Since ( now ) )
2024-04-28 11:47:05 +08:00
return
2023-11-13 15:21:54 +08:00
}
2024-12-03 14:12:47 +08:00
log . ZDebug ( ctx , "cron destruct chat records success" , "deltime" , deltime , "cont" , time . Since ( now ) )
2024-04-28 11:47:05 +08:00
}
2024-12-03 14:12:47 +08:00
if _ , err := crontab . AddFunc ( config . CronTask . CronExecuteTime , destructMsgsFunc ) ; err != nil {
2024-04-28 11:47:05 +08:00
return errs . Wrap ( err )
2023-11-13 15:21:54 +08:00
}
2024-07-16 10:46:21 +08:00
2024-08-01 16:12:41 +08:00
// scheduled soft delete outdated Msgs in specific time when user set `is_msg_destruct` feature.
2024-12-03 14:12:47 +08:00
clearMsgFunc := func ( ) {
2024-08-01 16:12:41 +08:00
now := time . Now ( )
ctx := mcontext . SetOperationID ( ctx , fmt . Sprintf ( "cron_%d_%d" , os . Getpid ( ) , now . UnixMilli ( ) ) )
2024-12-03 14:12:47 +08:00
log . ZDebug ( ctx , "clear msg cron start" , "now" , now )
2024-08-01 16:12:41 +08:00
2024-12-03 14:12:47 +08:00
conversations , err := conversationClient . GetConversationsNeedClearMsg ( ctx , & pbconversation . GetConversationsNeedClearMsgReq { } )
2024-08-01 16:12:41 +08:00
if err != nil {
log . ZError ( ctx , "Get conversation need Destruct msgs failed." , err )
return
}
2024-12-03 14:12:47 +08:00
_ , err = msgClient . ClearMsg ( ctx , & msg . ClearMsgReq { Conversations : conversations . Conversations } )
if err != nil {
log . ZError ( ctx , "Clear Msg failed." , err )
return
}
log . ZDebug ( ctx , "clear msg cron task completed" , "cont" , time . Since ( now ) )
2024-08-01 16:12:41 +08:00
}
2024-12-03 14:12:47 +08:00
if _ , err := crontab . AddFunc ( config . CronTask . CronExecuteTime , clearMsgFunc ) ; err != nil {
2024-08-01 16:12:41 +08:00
return errs . Wrap ( err )
2024-07-16 10:46:21 +08:00
}
2024-11-29 16:59:24 +08:00
// scheduled delete outdated file Objects and their datas in specific time.
deleteObjectFunc := func ( ) {
now := time . Now ( )
executeNum := 5
// number of pagination. if need modify, need update value in third.DeleteOutdatedData
pageShowNumber := 500
deleteTime := now . Add ( - time . Hour * 24 * time . Duration ( config . CronTask . FileExpireTime ) )
ctx := mcontext . SetOperationID ( ctx , fmt . Sprintf ( "cron_%d_%d" , os . Getpid ( ) , deleteTime . UnixMilli ( ) ) )
log . ZDebug ( ctx , "deleteoutDatedData" , "deletetime" , deleteTime , "timestamp" , deleteTime . UnixMilli ( ) )
if len ( config . CronTask . DeleteObjectType ) == 0 {
log . ZDebug ( ctx , "cron deleteoutDatedData not type need delete" , "deletetime" , deleteTime , "DeleteObjectType" , config . CronTask . DeleteObjectType , "cont" , time . Since ( now ) )
return
}
for i := 0 ; i < executeNum ; i ++ {
resp , err := thirdClient . DeleteOutdatedData ( ctx , & third . DeleteOutdatedDataReq { ExpireTime : deleteTime . UnixMilli ( ) , ObjectGroup : config . CronTask . DeleteObjectType } )
if err != nil {
log . ZError ( ctx , "cron deleteoutDatedData failed" , err , "deleteTime" , deleteTime , "cont" , time . Since ( now ) )
return
}
if resp . Count == 0 || resp . Count < int32 ( pageShowNumber ) {
break
}
}
log . ZDebug ( ctx , "cron deleteoutDatedData success" , "deltime" , deleteTime , "cont" , time . Since ( now ) )
}
if _ , err := crontab . AddFunc ( config . CronTask . CronExecuteTime , deleteObjectFunc ) ; err != nil {
return errs . Wrap ( err )
}
2024-08-01 16:12:41 +08:00
2024-09-12 10:38:17 +08:00
log . ZDebug ( ctx , "start cron task" , "CronExecuteTime" , config . CronTask . CronExecuteTime )
2024-04-28 11:47:05 +08:00
crontab . Start ( )
<- ctx . Done ( )
2024-05-07 21:05:41 +08:00
return nil
2023-11-13 15:21:54 +08:00
}