@@ -3993,6 +3993,231 @@ func (cmd *FunctionListCmd) readFunctions(rd *proto.Reader) ([]Function, error)
3993
3993
return functions , nil
3994
3994
}
3995
3995
3996
+ // FunctionStats contains information about the scripts currently executing on the server, and the available engines
3997
+ // - Engines:
3998
+ // Statistics about the engine like number of functions and number of libraries
3999
+ // - RunningScript:
4000
+ // The script currently running on the shard we're connecting to.
4001
+ // For Redis Enterprise and Redis Cloud, this represents the
4002
+ // function with the longest running time, across all the running functions, on all shards
4003
+ // - RunningScripts
4004
+ // All scripts currently running in a Redis Enterprise clustered database.
4005
+ // Only available on Redis Enterprise
4006
+ type FunctionStats struct {
4007
+ Engines []Engine
4008
+ isRunning bool
4009
+ rs RunningScript
4010
+ allrs []RunningScript
4011
+ }
4012
+
4013
+ func (fs * FunctionStats ) Running () bool {
4014
+ return fs .isRunning
4015
+ }
4016
+
4017
+ func (fs * FunctionStats ) RunningScript () (RunningScript , bool ) {
4018
+ return fs .rs , fs .isRunning
4019
+ }
4020
+
4021
+ // AllRunningScripts returns all scripts currently running in a Redis Enterprise clustered database.
4022
+ // Only available on Redis Enterprise
4023
+ func (fs * FunctionStats ) AllRunningScripts () []RunningScript {
4024
+ return fs .allrs
4025
+ }
4026
+
4027
+ type RunningScript struct {
4028
+ Name string
4029
+ Command []string
4030
+ Duration time.Duration
4031
+ }
4032
+
4033
+ type Engine struct {
4034
+ Language string
4035
+ LibrariesCount int64
4036
+ FunctionsCount int64
4037
+ }
4038
+
4039
+ type FunctionStatsCmd struct {
4040
+ baseCmd
4041
+ val FunctionStats
4042
+ }
4043
+
4044
+ var _ Cmder = (* FunctionStatsCmd )(nil )
4045
+
4046
+ func NewFunctionStatsCmd (ctx context.Context , args ... interface {}) * FunctionStatsCmd {
4047
+ return & FunctionStatsCmd {
4048
+ baseCmd : baseCmd {
4049
+ ctx : ctx ,
4050
+ args : args ,
4051
+ },
4052
+ }
4053
+ }
4054
+
4055
+ func (cmd * FunctionStatsCmd ) SetVal (val FunctionStats ) {
4056
+ cmd .val = val
4057
+ }
4058
+
4059
+ func (cmd * FunctionStatsCmd ) String () string {
4060
+ return cmdString (cmd , cmd .val )
4061
+ }
4062
+
4063
+ func (cmd * FunctionStatsCmd ) Val () FunctionStats {
4064
+ return cmd .val
4065
+ }
4066
+
4067
+ func (cmd * FunctionStatsCmd ) Result () (FunctionStats , error ) {
4068
+ return cmd .val , cmd .err
4069
+ }
4070
+
4071
+ func (cmd * FunctionStatsCmd ) readReply (rd * proto.Reader ) (err error ) {
4072
+ n , err := rd .ReadMapLen ()
4073
+ if err != nil {
4074
+ return err
4075
+ }
4076
+
4077
+ var key string
4078
+ var result FunctionStats
4079
+ for f := 0 ; f < n ; f ++ {
4080
+ key , err = rd .ReadString ()
4081
+ if err != nil {
4082
+ return err
4083
+ }
4084
+
4085
+ switch key {
4086
+ case "running_script" :
4087
+ result .rs , result .isRunning , err = cmd .readRunningScript (rd )
4088
+ case "engines" :
4089
+ result .Engines , err = cmd .readEngines (rd )
4090
+ case "all_running_scripts" : // Redis Enterprise only
4091
+ result .allrs , result .isRunning , err = cmd .readRunningScripts (rd )
4092
+ default :
4093
+ return fmt .Errorf ("redis: function stats unexpected key %s" , key )
4094
+ }
4095
+
4096
+ if err != nil {
4097
+ return err
4098
+ }
4099
+ }
4100
+
4101
+ cmd .val = result
4102
+ return nil
4103
+ }
4104
+
4105
+ func (cmd * FunctionStatsCmd ) readRunningScript (rd * proto.Reader ) (RunningScript , bool , error ) {
4106
+ err := rd .ReadFixedMapLen (3 )
4107
+ if err != nil {
4108
+ if err == Nil {
4109
+ return RunningScript {}, false , nil
4110
+ }
4111
+ return RunningScript {}, false , err
4112
+ }
4113
+
4114
+ var runningScript RunningScript
4115
+ for i := 0 ; i < 3 ; i ++ {
4116
+ key , err := rd .ReadString ()
4117
+ if err != nil {
4118
+ return RunningScript {}, false , err
4119
+ }
4120
+
4121
+ switch key {
4122
+ case "name" :
4123
+ runningScript .Name , err = rd .ReadString ()
4124
+ case "duration_ms" :
4125
+ runningScript .Duration , err = cmd .readDuration (rd )
4126
+ case "command" :
4127
+ runningScript .Command , err = cmd .readCommand (rd )
4128
+ default :
4129
+ return RunningScript {}, false , fmt .Errorf ("redis: function stats unexpected running_script key %s" , key )
4130
+ }
4131
+
4132
+ if err != nil {
4133
+ return RunningScript {}, false , err
4134
+ }
4135
+ }
4136
+
4137
+ return runningScript , true , nil
4138
+ }
4139
+
4140
+ func (cmd * FunctionStatsCmd ) readEngines (rd * proto.Reader ) ([]Engine , error ) {
4141
+ n , err := rd .ReadMapLen ()
4142
+ if err != nil {
4143
+ return nil , err
4144
+ }
4145
+
4146
+ engines := make ([]Engine , 0 , n )
4147
+ for i := 0 ; i < n ; i ++ {
4148
+ engine := Engine {}
4149
+ engine .Language , err = rd .ReadString ()
4150
+ if err != nil {
4151
+ return nil , err
4152
+ }
4153
+
4154
+ err = rd .ReadFixedMapLen (2 )
4155
+ if err != nil {
4156
+ return nil , fmt .Errorf ("redis: function stats unexpected %s engine map length" , engine .Language )
4157
+ }
4158
+
4159
+ for i := 0 ; i < 2 ; i ++ {
4160
+ key , err := rd .ReadString ()
4161
+ switch key {
4162
+ case "libraries_count" :
4163
+ engine .LibrariesCount , err = rd .ReadInt ()
4164
+ case "functions_count" :
4165
+ engine .FunctionsCount , err = rd .ReadInt ()
4166
+ }
4167
+ if err != nil {
4168
+ return nil , err
4169
+ }
4170
+ }
4171
+
4172
+ engines = append (engines , engine )
4173
+ }
4174
+ return engines , nil
4175
+ }
4176
+
4177
+ func (cmd * FunctionStatsCmd ) readDuration (rd * proto.Reader ) (time.Duration , error ) {
4178
+ t , err := rd .ReadInt ()
4179
+ if err != nil {
4180
+ return time .Duration (0 ), err
4181
+ }
4182
+ return time .Duration (t ) * time .Millisecond , nil
4183
+ }
4184
+
4185
+ func (cmd * FunctionStatsCmd ) readCommand (rd * proto.Reader ) ([]string , error ) {
4186
+
4187
+ n , err := rd .ReadArrayLen ()
4188
+ if err != nil {
4189
+ return nil , err
4190
+ }
4191
+
4192
+ command := make ([]string , 0 , n )
4193
+ for i := 0 ; i < n ; i ++ {
4194
+ x , err := rd .ReadString ()
4195
+ if err != nil {
4196
+ return nil , err
4197
+ }
4198
+ command = append (command , x )
4199
+ }
4200
+
4201
+ return command , nil
4202
+ }
4203
+ func (cmd * FunctionStatsCmd ) readRunningScripts (rd * proto.Reader ) ([]RunningScript , bool , error ) {
4204
+ n , err := rd .ReadArrayLen ()
4205
+ if err != nil {
4206
+ return nil , false , err
4207
+ }
4208
+
4209
+ runningScripts := make ([]RunningScript , 0 , n )
4210
+ for i := 0 ; i < n ; i ++ {
4211
+ rs , _ , err := cmd .readRunningScript (rd )
4212
+ if err != nil {
4213
+ return nil , false , err
4214
+ }
4215
+ runningScripts = append (runningScripts , rs )
4216
+ }
4217
+
4218
+ return runningScripts , len (runningScripts ) > 0 , nil
4219
+ }
4220
+
3996
4221
//------------------------------------------------------------------------------
3997
4222
3998
4223
// LCSQuery is a parameter used for the LCS command
0 commit comments