; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
classGrowthPlanLevelListener{constTAG='GrowthPlanLevelListener: ';/**
* @param HasOwner|Event $event
*/publicfunctionhandle($event){/** @var User $user */$user=$event->getOwner();// phpcs:ignore
// 此处获取版本信息,需要可序列化,所以不可以把这个listener实现Illuminate\Contracts\Queue\ShouldQueue
// 解决方式是先获取$withJpush,再生成一个实现ShouldQueue的job,并把$withJpush传进去
$withJpush=!LevelManager::isIncompatibleAgent();info(sprintf('%s user %d check and upgrade growth plan level.',self::TAG,$user->id));dispatch(newGrowthPlanLevelJob($user,$withJpush,$this->getNum(sprintf(GROWTH_PLAN_JOB_KEY,$user->id))));}privatefunctiongetNum($key){returnRedis::connection()->eval($this->preventRepeated(),1,$key);}// 不能让前一个job刚set完,后一个job没读到又set一次
privatefunctionpreventRepeated(){return<<<'LUA'
local hash = redis.call('get', KEYS[1])
local num = 1
if hash then
num = redis.call('incr',KEYS[1])
else
redis.call('set',KEYS[1],1)
end
return num
LUA;}}
classGrowthPlanLevelJobextendsJobimplementsShouldQueue{constTAG='GrowthPlanLevelJob';/**
* @var User $user
*/private$user;private$withJpush;/**
* 由于存在某个时间段触发某个用户很多个升级事件的行为,造成不必要的sql查询
* 所以需要记录当前job的编号以及存在的最大job编号,然后执行到这个人的升级任务的时候,只执行最后一个job
* @var int $jobNum
*/private$jobNum;public$tries=3;public$timeout=180;publicfunction__construct($user,$withJpush,$jobNum=1){$this->user=$user;$this->withJpush=$withJpush;$this->jobNum=$jobNum;}/**
* @throws \Illuminate\Contracts\Redis\LimiterTimeoutException
*/publicfunctionhandle(){$jobKey=sprintf(GROWTH_PLAN_JOB_KEY,$this->user->id);$count=Redis::connection()->get($jobKey);$info=['user_id'=>$this->user->id,'count'=>$count,'job_num'=>$this->jobNum];if(!$count){info(self::TAG.' $count is invalid.',$info);return;}if($count>$this->jobNum){info(self::TAG.' remain other job of upgrade this user growth plan.',$info);return;}info(self::TAG.' start executing job.',$info);Redis::connection()->funnel($funnelKey=self::TAG.$this->user->id)->limit($limit=1)->then(function()use($funnelKey,$limit){$levelManager=newLevelManager($this->user);$levelManager->checkAndUpLevel($this->withJpush);});Redis::connection()->del($jobKey);}}