gearman 实例一枚

有问题多看日志

gearman.log和gearmand.log


* related error messages: http://tech-lightnight.blogspot.jp/2013/04/start-with-gearman.html

* useful information:

https://groups.google.com/forum/#!topic/gearman/2LLx2iq1uhA

http://stackoverflow.com/questions/16815420/when-php-gearman-client-fails-to-connect-to-the-server-i-get-the-same-code-as-wh



start gearman : gearmand -d

stop gearman: gearadmin --shutdown (it seems that it doesn't work)

other commands: gearadmin --status  --workers

watch -n 1 "(echo status; sleep 0.1) | nc 127.0.0.1 4730"

----------------

有一个问题一直没有解决:

$ gearmand -d

$ command for starting gearman worker

$ waiting for gearman client to run tasks

开始时运行正常,client添加的任务都可以被worker及时处理,但是过了一段时间(可能是几天)后,client再发任务,worker就只能收到一部分或收不到任务。

-----------------


下面是一段调通的gearman程序:

1. GearmanClient

从数据库中取出一堆人checkins,将这堆人分成(小于等于)20组,然后为GearmanClient添加(小于等于)20个后台任务。

public function action_send_notification() {
        
        $event_id = Arr::get($_GET, 'event_id');
        $is_drill = Arr::get($_GET, 'is_drill');
    
        $sql = 'SELECT CheckIn.id as checkin_id, User.id as user_id, User.email, User.phonenumber, User.subscription, User.topicarn from CheckIn, User where CheckIn.eventID = :event_id and CheckIn.EmailStatus = 0 and CheckIn.SMSStatus = 0 and CheckIn.UserID = User.id';  
        $query = DB::query(Database::SELECT, $sql);  
        $query->param(':event_id', $event_id);  
        $checkins = $query->execute()->as_array(); 
        
        if (count($checkins) > 0) {
            $task_arr = $this->array_split($checkins, 20);

            try {
                $gmclient = new GearmanClient();
                $gmclient->addServer();
      
                for ($i=0; $i < count($task_arr); $i++) { 
                    $gmclient->addTaskBackground("sendmail", json_encode($task_arr[$i]));
                }

                $gmclient->runTasks();
            } catch (Exception $e) {
                $response_data['error'] = $e->getMessage();
            }
        }
        $response_data['status'] = 'client success';
        $this->response->body(json_encode($response_data));
    }

    private function array_split($array, $parts) {
        return array_chunk($array, ceil(count($array) / $parts));
    }



2. GearmanWorker

将worker设计为常驻进程,在父进程中fork四个子进程,每个子进程启动一个worker,不停地等待并处理任务。

一旦worker不能正常工作,则所在子进程exit,父进程中的wait将收到子进程退出的通知,于是重新fork一个子进程并启动补上一个worker。

</pre><p><pre name="code" class="php"><?php defined('SYSPATH') or die('No direct script access.');

    

class Task_Processmail extends Minion_Task {
    
    protected function _execute(array $params)
    {
        for ($i=0; $i < 4; $i++) { 
            $pid = pcntl_fork();
            if (0 == $pid) {      
                $gmworker = new GearmanWorker();
                $gmworker->addServer();
                $gmworker->addFunction("sendmail", "sendmail_fn");
                while (1) {
                    $gmworker->work();
                    if($gmworker->returnCode() != GEARMAN_SUCCESS)
                        break;
                }
                exit();
            } 
        }
    
        // 父进程
        while(TRUE) {
            $pid = pcntl_wait($status);
            
            // 重启关闭的子进程
            posix_kill($pid, SIGKILL);
            $pid = pcntl_fork();
            if (0 == $pid) {
                $gmworker = new GearmanWorker();
                $gmworker->addServer();
                $gmworker->addFunction("sendmail", "sendmail_fn");
                while (1) {
                    $gmworker->work();
                    if($gmworker->returnCode() != GEARMAN_SUCCESS)
                        break;
                }
                exit();
            } 
        }
    }

}

function sendmail_fn($job) {
    $workload = json_decode($job->workload(), true);
    // print_r($workload);

    foreach ($workload as $key => $value) {
        // $value = $workload;
        $checkin;
        try {
            $checkin = ORM::factory('Checkin')->where('id', '=', $value['checkin_id'])->find();
        } catch (Exception $e) {
            echo $e->getMessage();
            continue;
        }
 

        if ($checkin->loaded()) {  
            try {
                $content = array();
                $content['subject'] = "Emergency ".(!$value['is_drill'] ? "Situation Now" : "Drill Now");
                $content['content'] = "There is an emergency ".(!$value['is_drill'] ? "situation" : "drill").". Please click <a href=\"http://52.22.36.108/pinpoint/index.php/checkin?eventID=".$value['event_id']."&userID=".$value['user_id']."\">here</a> to checkin with Pinpoint.";

                $email = array();
                $email[] = $value['email'];
                AmazonSMS::sendmail($email, $content);

                //change status
                $checkin->EmailStatus = true;
                
                echo "send email ok.\n";
            } catch (Exception $e) {
                LOG::Instance()->add(Log::ERROR, 'Could not send email to :'.$value['email']);

                //change status
                $checkin->EmailStatus = false;

                echo "**send email fail: ";
                echo $e->getMessage();
            }              
        

            if (!empty($value['phonenumber']) && strlen($value['phonenumber']) > 8) {
                if (!empty($value['subscription']) && strlen($value['subscription'])>0) {
                    // LOG::Instance()->add(Log::INFO, 'SMS sent to :'.$value['phonenumber'], $value);
                    try {
                        AmazonSMS::sendMessage(array(
                            'arn' => $value['topicarn'],
                            'message' => "There is an emergency ".(!$Drill ? "situation" : "drill").". Please checkin with Pinpoint http://52.22.36.108/pinpoint/index.php/checkin?eventID=$event_id&userID=".$value['user_id']
                        ));

                        //change status
                        $checkin->SMSStatus = true;
                        
                    } catch (Exception $e) {
                        // LOG::Instance()->add(Log::ERROR, 'Could not send sms to :'.$value['phonenumber'], $e);

                        //change status
                        $checkin->SMSStatus = false;
                    }
                }
            }

            $checkin->save();
        } else {
            echo "ORM load fail";
        }
    }
}


 

下面的两幅图是间隔几个小时的两次进程查询:





可见,第四列数据(进程号)已经改变了,说明在此期间有进程exit并重新fork了新进程。


【语音分离】基于平均谐波结构建模的无监督单声道音乐声源分离(Matlab代码实现)内容概要:本文介绍了基于平均谐波结构建模的无监督单声道音乐声源分离方法,并提供了相应的Matlab代码实现。该方法通过对音乐信号中的谐波结构进行建模,利用音源间的频率特征差异,实现对混合音频中不同乐器或人声成分的有效分离。整个过程无需标注数据,属于无监督学习范畴,适用于单通道录音场景下的语音与音乐分离任务。文中强调了算法的可复现性,并附带完整的仿真资源链接,便于读者学习与验证。; 适合人群:具备一定信号处理基础和Matlab编程能力的高校学生、科研人员及从事音频处理、语音识别等相关领域的工程师;尤其适合希望深入理解声源分离原理并进行算法仿真实践的研究者。; 使用场景及目标:①用于音乐音频中人声与伴奏的分离,或不同乐器之间的分离;②支持无监督条件下的语音处理研究,推动盲源分离技术的发展;③作为学术论文复现、课程项目开发或科研原型验证的技术参考。; 阅读建议:建议读者结合提供的Matlab代码与网盘资料同步运行调试,重点关注谐波建模与频谱分解的实现细节,同时可扩展学习盲源分离中的其他方法如独立成分分析(ICA)或非负矩阵分解(NMF),以加深对音频信号分离机制的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值