Всем привет! Хотелось бы замутить микро scheduled таймер, который будет запускаться не раз в день, а к примеру каждые 5 минут. Кто-нить делал такое? Нагуглил вот что: https://developer.salesforce.com/forums?id=906F00000008yFvIAI Хорошее решение?
In order to schedule a job to run every 10 minutes you need to schedule 6 different jobs, since with spring 10' release, the min interval in which a job can run is every hour. You should run this code from the system log:
YourScheduleClass c = new YourScheduleClass(); String sch = '0 0 * * * ?'; System.schedule('Schedule Job1', sch, c);
YourScheduleClass c = new YourScheduleClass(); String sch = '0 10 * * * ?'; System.schedule('Schedule Job2', sch, c);
YourScheduleClass c = new YourScheduleClass(); String sch = '0 20 * * * ?'; System.schedule('Schedule Job3', sch, c);
YourScheduleClass c = new YourScheduleClass(); String sch = '0 30 * * * ?'; System.schedule('Schedule Job4', sch, c);
YourScheduleClass c = new YourScheduleClass(); String sch = '0 40 * * * ?'; System.schedule('Schedule Job5', sch, c);
YourScheduleClass c = new YourScheduleClass(); String sch = '0 50 * * * ?'; System.schedule('Schedule Job6', sch, c);
List<CronJobDetail> scheduleJobDetail = [SELECT Id FROM CronJobDetail WHERE Name = :SCHEDULER_NAME]; if (!scheduleJobDetail.isEmpty()){ system.debug('SCHEDULER IS RUNNING'); CronTrigger scheduleJob = [SELECT Id, State, NextFireTime FROM CronTrigger WHERE CronJobDetail.Id = :scheduleJobDetail[0].Id]; if (scheduleJob.NextFireTime == null || scheduleJob.NextFireTime > system.now().addSeconds(secondsForStart)) { system.abortJob(scheduleJob.id); system.schedule(SCHEDULER_NAME, sch, sj); } } else { system.schedule(SCHEDULER_NAME, sch, sj); } }
public static void Abort(){ List<CronJobDetail> cronJobDetails = [SELECT Id FROM CronJobDetail WHERE Name = :SCHEDULER_NAME]; if (cronJobDetails.isEmpty()){ return; }
List<CronTrigger> cronTriggers = [SELECT Id, State, NextFireTime FROM CronTrigger WHERE CronJobDetail.Id = :cronJobDetails[0].Id limit 1];
if (!cronTriggers.isEmpty()){ system.abortJob(cronTriggers[0].id); } }
public static Boolean isRunning(){ return [SELECT count() FROM CronJobDetail WHERE Name = :SCHEDULER_NAME] > 0; }
global void execute(SchedulableContext sc) { // Do any job. Run(); // run after 15 min. } }
Я боюсь разочаровать wilder'а и Дмитрия Лисовского, но ни один из этих вариантов не будет гарантированно работать при снижении требуемого интервала ниже чем где-то минут 10 и уж никак не 1 минута. Проблема в том что это отложенное выполнение кода, такое же как и batch jobs, future, time-based workflow, queable, etc. и SF чёрным по белому пишет "Salesforce schedules the class for execution at the specified time. Actual execution may be delayed based on service availability.", а также "When you call Database.executeBatch, Salesforce only adds the process to the queue. Actual execution may be delayed based on service availability." в общем поверьте, так будет во всех вышеперечисленных случаях - т.е. класс отработает в указанное время только в сферическом вакууме, а в реальных условиях, когда пойдёт нагрузка на инстанс форса время ожидания влёгкую подскакивает до 5 минут.
а к примеру каждые 5 минут.
Вообще это плохо! Зачем так часто? Это уже ошибка архитектуры!
А конкретная задача есть?
Вот конкретная задача из жизни - при изменении записи в форсе необходимо делать http callout, в оригинале необходимо было сериализовать данные и выложить их файликом на FTP сервис, чем ближе к real-time это будет сделано, тем лучше.
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать гарантировано, о чём сам форс любезно и заявляет.
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать гарантировано, о чём сам форс любезно и заявляет.
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
global with sharing class sch_GlobalScheduler implements Schedulable {
global void execute(SchedulableContext sc) { system.abortJob(sc.getTriggerID()); System.schedule('test', '34 ' + system.now().addMinutes(1).minute().format() + ' * * * ?', new sch_GlobalScheduler()); }
}
Пример выше убийства шедулера в execute самим собой улыбнул:D:D А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
Пример выше убийства шедулера в execute самим собой улыбнул:D:D А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
А может стоит сначала проверить, а потом писать ерунду ?
А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
Вот это точно бред Ничего что из execute нельзя делать future calls (асинхоннный код не может вызывать другой асинхронный) И кстати, аборт скудула с самом скедуле работает 100%, ничто не мешает убедиться, готовый код есть, даже 2)
Да, ладно, никто не обижает. Неправильное мнение, тоже мнение и лишный повод подискутировать. Зато Doz когда придет обрадуется, что его первый пост на форуме вызвал такую волну интереса со стороны сообщества
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
Что вы подразумеваете под "гарантированностью", то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
Что вы подразумеваете под "гарантированностью", то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.
Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.
Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.
Согласен, что real-time систему на форсе вряд ли удастся построить, а так - да - предложенный метод в принципе сработает в 99% случаев.