I have written batch apex code which will send a Good morning message to my Chatter group. I want to write scheduler class for this batch apex.
global class PostMessage Implements Database.batchable<sObject>
{
global Database.queryLocator start(Database.BatchableContext BC)
{
return Database.getqueryLocator([Select id,Name from CollaborationGroup where Name='Techila Group' LIMIT 1]);
}
global void execute(Database.BatchableContext BC,List<Account> acct)
{
FeedItem post=new FeedItem();
post.ParentID='0F9280000000B0t';
post.createdbyID=UserInfo.getuserId();
post.Body='Good Morning';
insert post;
}
global void finish (Database.BatchableContext BC)
{
}
}
Only one line of code needed to be executed in anonymous block
System.schedule('Every 0th min of hour', '0 0 * * * ?', new scheduledMerge());
Then as you say, you need to make a schedulable class... and execute your batch class from there.
global class schedule implements Schedulable {
global void execute(SchedulableContext SC) {
PostMessage batch = new PostMessage();
Database.executeBatch(batch, 200);
}
}
Check out the documentation for schedule classes:
https://developer.salesforce.com/docs/atlas.en-us.192.0.apexcode.meta/apexcode/apex_scheduler.htm
Related
I have a keyd stream of data that looks like:
{
summary:Integer
uid:String
key:String
.....
}
I need to aggregate the summary values in some time range, and once I achieved a specifc number , to flush the summary and all the of the UID'S that influenced the summary to database/log file.
after the first flush , I want to discare all the uid's from the memory , and just flush every new item immediatelly.
So I tried this aggregate function.
public class AggFunc implements AggregateFunction<Item, Acc, Tuple2<Integer,List<String>>>{
private static final long serialVersionUID = 1L;
#Override
public Acc createAccumulator() {
return new Acc());
}
#Override
public Acc add(Item value, Acc accumulator) {
accumulator.inc(value.getSummary());
accumulator.addUid(value.getUid);
return accumulator;
}
#Override
public Tuple2<Integer,List<String>> getResult(Acc accumulator) {
List<String> newL = Lists.newArrayList(accumulator.getUids());
accumulator.setUids(Lists.newArrayList());
return Tuple2.of(accumulator.getSum(), newL);
}
#Override
public Acc merge(Acc a, Acc b) {
.....
}
}
and in the aggregate process function , I flush the list to state, and if I need to save to dataBase I'm clearing the state and save flag in the state to indicate it.
But it seems crooked to me. And I'm not sure if that would work well for me.
Is there a better solution to this situation?
Work with a state inside a rich function. Keep adding the uid in your state and when the window triggers to flush the values. This page from the official documentation has an example.
https://ci.apache.org/projects/flink/flink-docs-release-1.11/dev/stream/state/state.html#using-keyed-state
For your case a ListState will work well.
EDIT:
The solution above is for non-window case. for window case simply use the aggrgation with apply function that can have a rich window function
i'm trying to write an apex class that checks a chekbox, on a custom object when a specific Date is less than 30 days from todays date. The class is supposed to run once a week to constantly check for Records that are supposed to be updated. I have absolutely no knowledge in Apex and my code is made up from various snippeds that I found in other Threads. I think I almost got it, but it keeps showing this error message: Method does not exist or incorrect signature: void DateCheck() from the type CustomersDateCheck.
Can somebody help me out here?
global class CustomersDateCheck implements Schedulable {
global void execute(SchedulableContext sc) {
DateCheck();}
public static void DateCheck(Customers__c[] objects){
for(Customers__c obj: objects){
if(obj.DateField > Date.today()){
continue;
}
else{
obj.FlowUpdateHelper__c = true;
}
}
}
}
Thanks in advance!
please pass the parameter in the function call that you are calling inside the execute method.
DateCheck(pass parameter)
Pass the List by query to customer object to fetch the required records.
e.g.
global void execute(SchedulableContext sc) {
List<Customers__c> customersList = [SELECT Id FROM Customers__c];
DateCheck();
}
OR
global void execute(SchedulableContext sc) {
Customers__c[] customersList = [SELECT Id FROM Customers__c];
DateCheck(customersList);
}
I have to execute many(more than 10) batch jobs one after other to make sure it doesn't exceeds governor limits.
I want to implements something like below but it doesn't work because stateful doesn't work for static.
public class MyBatch implements Database.Batchable<SObject>,
Database.Stateful
{
private String a;
private Static List<String> aList = new List<String>();
private static Integer currentIndex = 0;
static
{
aList = getAllAList();
}
public MyBatch(String a)
{
this.a = a;
}
public Database.QueryLocator start(Database.BatchableContext bc)
{
return Database.getQueryLocator('some query which may get 30k
records');
}
public void execute(Database.BatchableContext BC, List<sObject>
recordList)
{
System.debug('execute');
System.debug(recordList);
}
public void finish(Database.BatchableContext BC)
{
System.debug('finish');
//do I have another A.
if(currentIndex < aList.size())
{
cuurentIndex++;
System.debug('Starting another batch: '+ anotherA);
Database.executeBatch(new MyBatch(aList.get(currentIndex));
}
}
}
So here in finish method, currentIndex is always zero and because of that it always get first value in aList.
I also tried with some other static variables from other class as well but that also doesn't work.
Is there any way to achieve this thing without using database transactions?
You can't call it like this because the finish method is just called once at the end of (all) batches.
So the start and the execute method are important. Depending on the batchsize the query result will be devided into x chunks and the execute method will do the rest.
And since the finish method is just called once your index will be increment at the most once. If you increment it in the excute method it will increment each time a new batch(chunk) run
I have implemented through keeping currentIndex in batch class and passing it when calling next batch.
public class MyBatch implements Database.Batchable<SObject>,
Database.Stateful
{
private List<String> aList = null;
private Integer currentIndex;
public MyBatch(List<String> aList, Integer index)
{
this.aList = aList;
this.index = index;
}
public Database.QueryLocator start(Database.BatchableContext bc)
{
return Database.getQueryLocator('some query which may get 30k
records');
}
public void execute(Database.BatchableContext BC, List<sObject>
recordList)
{
System.debug('execute');
System.debug(recordList);
}
public void finish(Database.BatchableContext BC)
{
System.debug('finish');
//do I have another A.
currentIndex++;
if(currentIndex < aList.size())
{
System.debug('Starting another batch: ');
Database.executeBatch(new MyBatch(aList, currentIndex);
}
}
}
So idea here is to keep index to batch as private member not as static and check if size doesn't exceed then trigger next batch.
I have a Laravel 4 test class with some tests for which I want to seed my database before running the tests. Using the setup() function to reseed for each test takes far too long. However, when I try seeding in the static setupBeforeClass() function or the constructor, I obviously can't use the $this->seed() method.
But neither can I use programmatic Artisan commands, because when I do, I get the following error: PHP Fatal error: Class 'Artisan' not found in <test class name>.
Here is the code I'd like to use to seed:
Artisan::call('migrate:refresh');
Artisan::call('db:seed', array('--class'=>'TestSeeder');
Please let me know how I can seed my database once per test class rather than per test case
An "improvised" but pretty clean imho way to achieve a similar effect would be to do this in setUp, but have it run only once (similar to what setupBeforeClass does) like this:
use Illuminate\Support\Facades\Artisan;
class ExampleTest extends TestCase {
protected static $db_inited = false;
protected static function initDB()
{
echo "\n---initDB---\n"; // proof it only runs once per test TestCase class
Artisan::call('migrate');
// ...more db init stuff, like seeding etc.
}
public function setUp()
{
parent::setUp();
if (!static::$db_inited) {
static::$db_inited = true;
static::initDB();
}
}
// ...tests go here...
}
...this is my solution and it seems simple enough and works fine, solving the performance problems of seeding and rebuilding the db structure before every test run. But remember, the "right" way to do testing, that gives you the greatest confidence your tests methods don't get subtly interdependent in bug-hiding ways, is to re-seed your db before every test method, so just put seeding code in plain setUp if you can afford the performance penalty (for my test cases, I couldn't afford it, but ymmv...).
I had the same problem and solved with this
passthru('cd ' . __DIR__ . '/../.. & php artisan migrate:refresh & db:seed --class=TestSeeder');
This is so far the best solution I found
class ExampleTest extends TestCase {
/**
* This method is called before
* any test of TestCase class executed
* #return void
*/
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
print "\nSETTING UP DATABASE\n";
shell_exec('php artisan migrate --seed');
}
/**
* This method is called after
* all tests of TestCase class executed
* #return void
*/
public static function tearDownAfterClass()
{
shell_exec('php artisan migrate:reset');
print "\nDESTROYED DATABASE\n";
parent::tearDownAfterClass();
}
/** tests goes here **/ }
Update:
Laravel 5,6,7,8,9
https://laravel.com/docs/9.x/database-testing
use RefreshDatabase;
Outdated:
This trait is a wonderful way of resetting the database
<?php
namespace Tests;
use Illuminate\Support\Facades\Artisan;
trait MigrateFreshAndSeedOnce
{
/**
* If true, setup has run at least once.
* #var boolean
*/
protected static $setUpHasRunOnce = false;
/**
* After the first run of setUp "migrate:fresh --seed"
* #return void
*/
public function setUp() : void
{
parent::setUp();
if (!static::$setUpHasRunOnce) {
Artisan::call('migrate:fresh');
Artisan::call(
'db:seed',
['--class' => 'CompleteTestDbSeeder'] //add your seed class
);
static::$setUpHasRunOnce = true;
}
}
}
You can do now:
protected function setUp()
{
parent::setUp();
$this->seed();
}
in your setUp() method for your test.
The seed() method accepts as a parameter the seeder class.
public function seed($class = 'DatabaseSeeder')
{
$this->artisan('db:seed', ['--class' => $class]);
return $this;
}
I have a class that returns an IEnumerable. I then execute these tasks in order. Let's say the class is TaskProvider.
public class TaskProvider {
public IEnumerable<Task> SomeThingsToDo() { return work; }
}
I am executing these with the following:
public void ExecuteTasks(IEnumerable<Task> tasks)
{
var enumerator = tasks.GetEnumerator();
ExecuteNextTask(enumerator);
}
static void ExecuteNextTask(IEnumerator<Task> enumerator)
{
bool moveNextSucceeded = enumerator.MoveNext();
if (!moveNextSucceeded) return;
enumerator
.Current
.ContinueWith(x => ExecuteNextTask(enumerator));
}
Now I have a situation where I might have multiple instances of TaskProvider, each generating a list of tasks. I want each list of tasks to be executed in order, meaning that all the tasks from one provider finish before the next one starts.
Then, most importantly, I need to know when all the tasks are completed.
What's the TPL way of accomplishing this?
(FWIW, I'm using the Async CTP for Silverlight.)
Here's the approach I took, and so far all my tests are passing.
First, I created a unioned enumerable of all the tasks from the various providers:
var tasks = from provider in providers
from task in provider.SomeThingsToDo()
select task;
I believe that part of my original problem was that I did a ToList (more or less) and thus began the execution of the tasks prematurely.
Next, I added a callback to ExecuteTasks and ExecuteNextTask. Admittedly, not as clean as I'd hoped. Here's the revised implementation:
public void ExecuteTasks(IEnumerable<Task> tasks, Action callback)
{
var enumerator = tasks.GetEnumerator();
ExecuteNextTask(enumerator, callback);
}
static void ExecuteNextTask(IEnumerator<Task> enumerator, Action callback)
{
bool moveNextSucceeded = enumerator.MoveNext();
if (!moveNextSucceeded)
{
if (callback != null) callback();
return;
}
enumerator
.Current
.ContinueWith(x => ExecuteNextTask(enumerator, callback));
}
I didn't need a thread-safe structure for storing the list of tasks, because the list is generated only once.
at worst you could have a static concurrentqueue of Ienumerables which you ExecuteNextTask method works it's way through...
something like:
public static class ExecuteController {
private static ConcurrentQueue<IEnumerable<Task>> TaskLists = new ConcurrentQueue<IEnumerable<Task>>();
public void ExecuteTaskList(IEnumerable<Task> tasks) {
TaskLists.Enqueue(tasks);
TryStartExec();
}
public void TryStartExec() {
check if there is a new task list and if so exec it with your code.
possibly need to lock around the dequeue but i think there is an atomic dequeue method on concurrent queue..
}
}