- Laravel background jobs
12345678910
WT форуми -> PHP MySQL ASP.NET -> Laravel background jobs
Създайте нова тема Напишете отговор 
Автор Съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 6:57 am      Отговорете с цитат


Revelation написа:
teroristd написа:
Very Happy не в смисъл командата работи, но се изпълнява един път. Явно трябва да мисля нещо друго. Имам VMware на лаптопа. Дали ще свърши някаква работа?


Между другото, използвай така task scheduler-а и ще се оправи.

Цитат:

schtasks /create /sc minute /mo 1 /tn "Laravel Scheduler" /tr "php C:\xampp\htdocs\Game\artisan schedule:run"


Сега го тествах и проверих логовете и разбрах защо не се получава.
Така написан скеджълъра си работи идеално при мен.

П.П. Оказа се, че schedule:run си разпознава операционната система и си добавя нужните параметри след това. За това е нужно само да си се вика schedule:run.


Благодаря, и при мен работи. Сега трябва да се върна към схемата която ми изпрати, и да продължа към следващата част на задачката Smile .
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 11:11 am      Отговорете с цитат


Горе долу схванах картинката, само не разбрах как да стартирам втората задача при клик от юзъра?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Потребител
Потребител

Регистриран на: 24/03/2013 3:23 pm

Support: 57
Bonus: 114
Мнения: 764
Мнение 27/04/2018 2:11 pm      Отговорете с цитат


Правиш си Queue Job(UpdateResourcesPerMin), който ъпдейтва resources_per_min, като в контролера ще му подаваш user_id.

Правиш си един контролер, който приема като параметър коя сграда е пусната. Да речем:

PHP code:

class BuildingController extends Controller {
public function build(Building $building) {
UpdateResourcesPerMin::dispatch([
'user_id' => app()->user()->id,
'mine' => $building // за да знаеш кое поле да обновиш
])->delay(now()->addMinutes($building->getDuration()));
}
}


и в рутера да речем можеш да използваш GET или POST в зависимост как си изградиш нещата.

PHP code:

Route::get('/build/{building}', 'BuildingController@build');


и следователно

HTML code:

<a href="{{ url('build', ['building' => 'gold']) }}">Build Gold Mine</a>


Нещата съм ги написал просто образно. Доста неща ще трябва да обмислиш как да ги направиш, като например Building $building какво трябва да е, за да взимаш правилната сграда/ферма и да взимаш правилните данни, като getDuration().

Но се надявам, че хвана картинката как да извикаш queue-то.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 2:17 pm      Отговорете с цитат


Да горе долу схванах Smile, но ще се стартира ли Queue-то ако викам dispatch извън Scheduler-а? Питам защото четох че за да стартираш Queue трябва да подадеш команда php artisan queue:work.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 2:43 pm      Отговорете с цитат


Значи Queue-то се изпълнява но само един път защото е извън Scheduler-а.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Потребител
Потребител

Регистриран на: 24/03/2013 3:23 pm

Support: 57
Bonus: 114
Мнения: 764
Мнение 27/04/2018 2:52 pm      Отговорете с цитат


Ти не ти трябва Scheduler-а за тази цел. Просто му задай delay(now()->addMinutes(time)) като time е времето, за което трябва да се построи сградата.

А иначе, за да работи правилно queue, трябва да си направиш таблица в базата данни:

PHP code:

php artisan queue:table
php artisan migrate
php artisan queue:work


иначе дори и да сложиш delay няма да работи правилно и ще вика веднага dispatch().
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 3:09 pm      Отговорете с цитат


Аз съм му направил таблицата, но тука проблема е че когато е извън sceduler-a трябва да му подам командата ръчно. Разбираш ли ме какво имам на предвид?

За да го обясня по цветно, в началото като стартирам scheduler-a почва да се трупа злато през една минута, но камъните си стоят нула. Целта е когато играча построи мината да се стартира втората задача и да почнат да се трупат и камъни, но това не се случва защото queue-to е извън цикъла.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Потребител
Потребител

Регистриран на: 24/03/2013 3:23 pm

Support: 57
Bonus: 114
Мнения: 764
Мнение 27/04/2018 3:43 pm      Отговорете с цитат


Ще опитам да ти разясня отново стъпка по стъпка:

0. Тази задача не трябва да участва в scheduler-а. За да се изпълняват queue работите, трябва да имаш стартиран php artisan queue:work

1. Queue работата(ще я кръстя UpdateResourcesPerMinJob) има за цел да ти вземе данните(взети и подадени от контролера), да речем user_id и името на сградата - да речем gold(това ще е името и на полето ти в базата данни, което ще трябва да се ъпдейтне), както също и данни като например след като се построи сградата с колко трябва да увеличиш полето gold.

2. Правиш си контролер, на който работата му ще е да строи сгради. В него идеята е да извикаш UpdateResourcesPerMinJob и да го dispatch()-неш като на dispatch() подаваш нужните данни(user_id, building name и т.н., като ти препоръчвам building да е обект, с който да можеш да работиш в самото queue) + му закачаш един delay(), който ще е времето, което ще е нужно да се построи сградата. Така, когато натиснеш бутона за построяване, де факто dispatch()-ваш опашката. По-лесно казано, регистрираш я в базата данни и queue:work вече ще знае кога тази опашка трябва да се извика и да се изпълни.
И вече, да речем, ако на сградата са и били нужни 5мин. да се построи, след тези 5мин. опашката ще се изпълни, ще ти ъпдейтне таблицата resources_per_min за съответната колона(име на сграда) и оттам вече, теб не те интересува scheduler-а какво върши, защото той си изпълнява неговата работа да вика командата, която ъпдейтва ресурсите на потребитела. Съответно, след като се ъпдейтне таблица след построяването на сградата, при следващия тик на scheduler-а, той просто ще си вземе новите данни от базата данни ще ъпдейтва според това, какво има там.


Аз май няколко точки ги обясних в т.2, но са просто навързани.

Надявам се, че започваш да разбираш за какво говоря. Ако не, ще видя, ако ми остане някакво време да ти го реализирам, но ти препоръчвам да се справиш сам, за да разбереш процеса на работа.
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 4:49 pm      Отговорете с цитат


Revelation написа:
Надявам се, че започваш да разбираш за какво говоря. Ако не, ще видя, ако ми остане някакво време да ти го реализирам, но ти препоръчвам да се справиш сам, за да разбереш процеса на работа.


Аз искам сам да си го направя. В крайна сметка целта е да се науча. Нещо не мога да схвана логиката. Значи ако разбирам правилно sheduler-a само следи дали има построена дадената мина. Ако няма не ъпдейтва. На queue-тата работата им е да строят сгради.

Само че тука виждам един проблем. Поправи ме ако греша.
Да кажем стартирам php artisan queue:work но в момента в който затворя конзолата той спира да работи. Така ли е?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
anonimen
Активен
Активен

Регистриран на: 11/06/2012 8:07 pm

Support: 161
Bonus: 321
Мнения: 1509
Мнение 27/04/2018 5:00 pm      Отговорете с цитат


Цитат:
Да кажем стартирам php artisan queue:work но в момента в който затворя конзолата той спира да работи. Така ли е?


Да, защото конзолата е parent process на стартираната php команда. Виж как в уиндоус да стартираш background process.

П.п. ето ти: https://superuser.com/questions/198525/how-can-i-execute-a-windows-command-line-in-background

Цитат:
START /B program
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Revelation
Потребител
Потребител

Регистриран на: 24/03/2013 3:23 pm

Support: 57
Bonus: 114
Мнения: 764
Мнение 27/04/2018 5:35 pm      Отговорете с цитат


Пак стъпка по стъпка:

Scheduled Tasks
1. Scheduler-а се интересува да има направена команда update:resources
2. Командата се интересува да има създадена таблица resources_per_min

Процес на работа:
1. Schduler-а се изпълнява всяка минута, проверява дали има задачи за изпълнение и ако има ги изпълнява. В случая ти имаш.
2. Командата се изпълнява, взима текущите данни от resources_per_min и ъпдейтва съответно стойностите в resources. Край.
3. Връщаме се на т1.

Добавка: Scheduler-а винаги се изпълнява щом му дойде времето(в твоя случай всяка минута). В твоя случай, той не следи дали има построена дадена мина. Него го интересува само данните да са налични, за да не праска грешки. Дали всички стойности ще са 0, не го интересува, той ще си се изпълнява.

Важно: Тази команда има за задача да ъпдейтва на всички потребители ресурсите. За тази цел в командата трябва да завърташ цикъл с всички потребители.

Queue Jobs обяснени за твоята задача
1. Queue Jobs(в твоя случай UpdateResourcesPerMinJob) се интересува от данните на потребителя и данните на сградата, която строиш.
1.1. Данните на потребителя ти трябват, за да знаеш на кой точно потребител трябва да ъпдейтнеш данните в resources_per_min
1.2. Данните за сградата ти трябват, за да знаеш коя колона да промениш. Ако строиш каменна мина, да промениш стойността на кеманната мина. Съответно и за другите.
Съвет: Изпращай обект Building(за пример), от който ще можеш да взимаш името на сградата, нивото, ресурсите след всяко ниво, които трябва да получаваш(това е най-важно всъщност) и т.н.
2. Да имаш queue worker пуснат.
Информация: Да, винаги трябва да е отворена или както ти казаха, да пуснеш процеса в бекграунд. Но това са подробности, които не ти трябват, ако го правиш само с научна цел.

Процес на работа
1. Имаш контролер, който управлява строенето на всички сгради.
1.1. Контролера не се интересува каква ще е сградата, стига да е сграда.
2. При извикване на съответния метод, който в случая се вика при кликане на бутон за строене на сграда, има за цел да регистрира задачата - UpdateResourcesPerMinJob::dispatch(array params)
3. Ако не зададеш delay, то задачата ще се изпълни веднага, но ни не искаме това.
4. Закачаш на dispatch() един delay(), който трябва да е времето за строене на сградата, за да може чак след като строежа приключи, задачата да се изпълни.
5. Сградата е построена, изпълнява се задачата, ъпдейтва resources_per_min и приключва.

Информация: Задачата трябва да се регистрира само и единствено, когато е натиснат бутон за строене на сграда или респективно, когато се извика съответния action в контролера, И трябва да се изпълнява винаги след като сградата се построи или иначе казано със закъснение(delay)

Надявам се вече да е малко по-ясно какво се случва, че се уморих. Very Happy
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
teroristd
Редовен
Редовен

Регистриран на: 18/02/2010 1:50 pm

Support: 83
Bonus: 178
Мнения: 1768
Мнение 27/04/2018 6:25 pm      Отговорете с цитат


Руска печка съм знам Very Happy, ама какво да правя. Мисля че разбрах от къде идва объркването ми. В графиката която ми даде в началото двете таблици са с абсолютно еднакви имена на колоните. Да вземем за пример полето gold. Какво се очаква да съдържа в едната и в другата таблица? Името на мината или там се трупа златото?
Върнете се в началото
Вижте профила на потребителя Изпратете лично съобщение
Покажи мнения от преди:    
Създайте нова тема   Напишете отговор    web-tourist.net Форуми -> PHP MySQL ASP.NET Часовете са според зоната GMT + 2 Часа
12345678910
Страница 4 от 10


 
Идете на:  
Не Можете да пускате нови теми
Не Можете да отговаряте на темите
Не Можете да променяте съобщенията си
Не Можете да изтривате съобщенията си
Не Можете да гласувате в анкети