We're trying to implement dynamic batch processes to dispatch different classes. Specifically, we have integrated multiple systems, and depending on certain events, we dispatch callouts to those systems.
We have a simple object that remembers the name of the integration to call and the record to integrate with, and custom settings to determine how many records to process at once, etc. There is a scheduler that polls the database every few minutes and calls the appropriate class, which must implement a particular interface.
Now, we're adding a new interface to accommodate larger data volumes, and here's where the problems start.
The original interface looks like this:
public interface ClassicIntegration {
boolean initialize();
void execute(List<List<Queued_Item__c>> items, String method);
void finish();
}
Traditionally, the classes that use this interface return true if they initialize okay (they never fail at this point), and then dispatch the data inside execute() to a future method, and have empty finish() methods.
Those calls end up executing immediately after the scheduler performs its work, and everything is done within seconds.
However, there's an inherent limit with this system; we could only process a handful of records at a time, because of the 10 future call limit and the 10 callout limit; loading 10,000 records takes over 3 hours. QA once tried to import 450,000 records, only to find out it'd take a week to deliver all the messages. This led to a design for a new interface. The primary benefit of the new interface was to have the class be batchable, so I wrote it like this:
public interface BatchIntegration extends Database.Batchable<Queued_Item__c> {
void initialize(List<List<Queued_Item__c>> items, String method);
}
The signature was meant to be nearly the same to preserve as much of the original code as possible (because the other classes wouldn't be migrated immediately).
However, at this point, I'm running into a problem. I'm calling the batch like this:
BatchIntegration impl = (BatchIntegration)Type.forName(implClass).newInstance();
impl.initialize(queueItems, actionMethod);
Database.executeBatch(impl, batchSize);
This batch is assigned a Job ID, which I can verify in debug statements, and appears in the queue, which I can verify under Apex Jobs. However, it remains in the Queued status and never even attempts to start, while in the meantime, dozens of other future methods, scheduled classes, and even different batches (I created a test class that simply generates random accounts), and all of them run by just fine.
I can't seem to find any documentation about possible bugs, but surely this can't be right? Are we "allowed" to extend interfaces? Or does the system have some limitation regarding this that's simply not documented? The code compiles, and it even runs, as evidenced by the results, but the queued item itself won't execute.
Does anyone have any further information on this, or should I attempt to log this as a bug?