Всем привет! Хотелось бы замутить микро scheduled таймер, который будет запускаться не раз в день, а к примеру каждые 5 минут. Кто-нить делал такое? Нагуглил вот что: https://developer.salesforce.com/forums?id=906F00000008yFvIAI Хорошее решение?
Всем привет!
Хотелось бы замутить микро scheduled таймер, который будет запускаться не раз в день, а к примеру каждые 5 минут.
Кто-нить делал такое?
Нагуглил вот что: https://developer.salesforce.com/forums?id=906F00000008yFvIAI
Хорошее решение?
[quote="DevNull"]Всем привет!
Хотелось бы замутить микро scheduled таймер, который будет запускаться не раз в день, а к примеру каждые 5 минут.
Кто-нить делал такое?
Нагуглил вот что: https://developer.salesforce.com/forums?id=906F00000008yFvIAI
Хорошее решение?[/quote]
А лимитов не боишься?
Ты вот про такую реализацию?
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);
Ты вот про такую реализацию?
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:
[code]
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);
[/code]
Боюсь! Напомни плиз лимиты на scheduled. Пока ХЗ. Попросили узнать если такая возможность с ее недостатками.
[quote="Gres"]А лимитов не боишься?[/quote]
Боюсь!
Напомни плиз лимиты на scheduled.
[quote="RasMisha"]А что "внутри" собираешься делать?[/quote]
Пока ХЗ. Попросили узнать если такая возможность с ее недостатками.
Вообще это плохо! Зачем так часто? Это уже ошибка архитектуры!
[quote="DevNull"]Боюсь!
Напомни плиз лимиты на scheduled.[/quote]
[quote]
The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period - 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater
[/quote]
global class CustomScheduler implements Schedulable{
private static final String SCHEDULER_NAME = 'CustomScheduler'; private static final Integer DEFAULT_SCHEDULER_INTERVAL_SECONDS = 60 * 15; // 15 min.
public static void Run() { Run(DEFAULT_SCHEDULER_INTERVAL_SECONDS); }
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. } }
[quote="Дима Лисовский"][quote="Gres"]А конкретная задача есть?[/quote]
Например формирование каждый час PDF отчёта и отправка по email.[/quote]
Каждый час еще может быть, но каждые 5 мин?
[quote="Dmitry Shnyrev"][quote="wilder"]У меня вообще каждую минуту запускается и что?[/quote]
А что он делает?[/quote]
Он проверяет настройки и в зависимости от этого запускает другие батчи или скедулеры.
А каждую минуту пускать это так критично? Я так понимаю в списке schedeled jobs у тебя висит 60 шедулеров через час со смещением в 1 минуту?
[quote="Dmitry Shnyrev"]А каждую минуту пускать это так критично?
Я так понимаю в списке schedeled jobs у тебя висит 60 шедулеров через час со смещением в 1 минуту?[/quote]
Нет у меня висит только один, еоторый запускается каждую минуту. Рассказать как это сделать?
[quote="Dmitry Shnyrev"]Ну конечно расскажи![/quote]
Проверяешь параметры и если ничего делать не нужно убиваешь скедуллер и запускаешь его же только через минуту.
Если что-то нужно делать, то делаем. Убиваем скедуллер и запускаем через минуту.
И это все происходит внутри текущего скедулера.
Проверяешь параметры и если ничего делать не нужно убиваешь скедуллер и запускаешь его же только через минуту.
Если что-то нужно делать, то делаем. Убиваем скедуллер и запускаем через минуту.
[quote="wilder"]Проверяешь параметры и если ничего делать не нужно убиваешь скедуллер и запускаешь его же только через минуту.
Если что-то нужно делать, то делаем. Убиваем скедуллер и запускаем через минуту.
И это все происходит внутри текущего скедулера.[/quote]
[quote="Дима Лисовский"]Выше мой пример :)[/quote]
Выше мой пример :)
Мне твой пример нифига не нравиться. Все можно упростить и не делать никаких селектов.
[quote="Дима Лисовский"]Ну тогда показывай свой :)[/quote]
[code]
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());
}
}
[/code]
Я боюсь разочаровать 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'а и Дмитрия Лисовского, но ни один из этих вариантов не будет гарантированно работать при снижении требуемого интервала ниже чем где-то минут 10 и уж никак не 1 минута. Проблема в том что это отложенное выполнение кода, такое же как и batch jobs, future, time-based workflow, queable, etc. и SF чёрным по белому пишет [b]"Salesforce schedules the class for execution at the specified time. Actual execution may be delayed based on service availability."[/b], а также [b]"When you call Database.executeBatch, Salesforce only adds the process to the queue. Actual execution may be delayed based on service availability."[/b] в общем поверьте, так будет во всех вышеперечисленных случаях - т.е. класс отработает в указанное время только в сферическом вакууме, а в реальных условиях, когда пойдёт нагрузка на инстанс форса время ожидания влёгкую подскакивает до 5 минут.
[quote="Dmitry Shnyrev"][quote="DevNull"]а к примеру каждые 5 минут.[/quote]
Вообще это плохо! Зачем так часто? Это уже ошибка архитектуры![/quote]
[quote="Gres"]А конкретная задача есть?[/quote]
Вот конкретная задача из жизни - при изменении записи в форсе необходимо делать http callout, в оригинале необходимо было сериализовать данные и выложить их файликом на FTP сервис, чем ближе к real-time это будет сделано, тем лучше.
[quote="Дима Лисовский"]Да, не разочарованы, знаем :)[/quote]
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Да, не разочарованы, знаем :)
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
[quote="ilya leshchuk"][quote="Дима Лисовский"]Да, не разочарованы, знаем :)[/quote]
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)[/quote]
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Да, не разочарованы, знаем :)
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать гарантировано, о чём сам форс любезно и заявляет.
[quote="wilder"][quote="ilya leshchuk"][quote="Дима Лисовский"]Да, не разочарованы, знаем :)[/quote]
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)[/quote]
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.[/quote]
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать [b]гарантировано[/b], о чём сам форс любезно и заявляет.
Да, не разочарованы, знаем :)
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать гарантировано, о чём сам форс любезно и заявляет.
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
[quote="ilya leshchuk"][quote="wilder"][quote="ilya leshchuk"][quote="Дима Лисовский"]Да, не разочарованы, знаем :)[/quote]
Ну это главным образом было для wilder'а, у вас всё таки разумные 15 минут стояли :)[/quote]
Тут наверное уже пришла моя очередь разочаровывать - работает и очень даже хорошо. Учитывая что у меня он такой один, который крутиться каждую минуту. А в общей сложности если зарустить все возможные скедуллеры, то их число не превысит 10. Так что работает.[/quote]
Нисколько не разочаровали. У Ашманова как-то читал список фраз, которые разработчик не должен произносить ни в коем случае, одна из них была "А у меня на машине всё работает!". Речь идёт не о том что оно не будет работать вообще, а о том что оно не будет работать [b]гарантировано[/b], о чём сам форс любезно и заявляет.[/quote]
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
Ну тогда показывай свой :)
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 метод передавая в него айдишку и затем там же его запускать.
[quote="wilder"][quote="Дима Лисовский"]Ну тогда показывай свой :)[/quote]
[code]
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());
}
}
[/code][/quote]
Пример выше убийства шедулера в execute самим собой улыбнул:D:D
А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
Пример выше убийства шедулера в execute самим собой улыбнул:D:D А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
А может стоит сначала проверить, а потом писать ерунду ?
[quote="Doz"]Пример выше убийства шедулера в execute самим собой улыбнул:D:D
А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.[/quote]
А может стоит сначала проверить, а потом писать ерунду ?
Разве общая очередь выполнения влияет на schedule?
[quote="Doz"]Пример выше убийства шедулера в execute самим собой улыбнул:D:D [/quote]
Doz, ты точно смелый парень раз решил высмеять код товарища Wilder :D
А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.
Вот это точно бред Ничего что из execute нельзя делать future calls (асинхоннный код не может вызывать другой асинхронный) И кстати, аборт скудула с самом скедуле работает 100%, ничто не мешает убедиться, готовый код есть, даже 2)
[quote="Doz"]А ничего, что он не может убить сам себя?) Нужно отдельно выносить убийство шедулера в @Future метод передавая в него айдишку и затем там же его запускать.[/quote]
Вот это точно бред :) Ничего что из execute нельзя делать future calls (асинхоннный код не может вызывать другой асинхронный)
И кстати, аборт скудула с самом скедуле работает 100%, ничто не мешает убедиться, готовый код есть, даже 2)
Да, ладно, никто не обижает. Неправильное мнение, тоже мнение и лишный повод подискутировать. Зато Doz когда придет обрадуется, что его первый пост на форуме вызвал такую волну интереса со стороны сообщества
Да, ладно, никто не обижает.
Неправильное мнение, тоже мнение и лишный повод подискутировать.
Зато Doz когда придет обрадуется, что его первый пост на форуме вызвал такую волну интереса со стороны сообщества :D
[quote="Gres"]
Что ж вы так сразу обижаете парня?)[/quote]
Ни в коем случае не хотел обидеть
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
Что вы подразумеваете под "гарантированностью", то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.
[quote="wilder"]Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.[/quote]
Что вы подразумеваете под [b]"гарантированностью"[/b], то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.
Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.
Что вы подразумеваете под "гарантированностью", то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.
Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.
[quote="ilya leshchuk"][quote="wilder"]Как раз таки он работает гарантированно, потому что используется своя очередь, которая никак не зависит от очереди Салесфорса. И да работает не только на моей машине. И если уже быть совсем точным, то запускается мой скедуллер не каждую минуту, а через минуту после окончания своей работы.[/quote]
Что вы подразумеваете под [b]"гарантированностью"[/b], то что он запустится в принципе? Если да, то это гарантированно, но не вашей очередью, а самим форсом. Я же под этим имел в виду что не гарантируется соблюдение интервала и точность времени запуска.[/quote]
Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.
Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.
Согласен, что real-time систему на форсе вряд ли удастся построить, а так - да - предложенный метод в принципе сработает в 99% случаев.
[quote="wilder"]Ну что я могу сказать. Судя по вашему профилю вы работаете с салесфорсом достаточно давно, что бы понять что тот смысл который вы вкладываете в слово гарантированно точно не вяжется с салесфорсом.
А теперь по теме. Я написал что мой скедулер запускается через минуту после его заверщения. В принципе практически всегда это получается каждую минуту. Так что если обращаться к теории вероятности и сравнить результат со смыслом свого гарантированно, то мы имеем верное равенство. Остальное в пределах погрешности.
Но если вам нужно импрементировать real-time сисмему с опросом чего-то именно каждую минуту - это точно должен быть не салесфорс.[/quote]
Согласен, что real-time систему на форсе вряд ли удастся построить, а так - да - предложенный метод в принципе сработает в 99% случаев.