You don't need to specify a length for batchable by a query. You can specify it by any other type of data that is Iterable. For example, you can choose to use some arbitrary number as the limit:
public class MyBatchable implements Iterator<Integer>, Iterable<Integer>, Database.Batchable<Integer>, Database.Stateful, Database.AllowsCallouts {
@TestVisible Integer remainingCount = 5000;
public integer next() {
return remainingCount--;
}
public boolean hasNext() {
return remainingCount > 0;
}
public iterator<integer> iterator() {
return this;
}
public Iterable<Integer> start(Database.BatchableContext bc) {
return this;
}
public void execute(Database.BatchableContext bc, Integer[] values) {
// Do your stuff here
// If you run out of stuff to do, System.abortJob(bc.getJobId());
}
public void finish(Database.BatchableContext bc) {
// Be sure to reset remainingCount if you need to process more data,
// or you'll enter an infinite batch loop.
// You can call another Database.executeBatch(this, 1); here if you need more processing.
}
}
The bits left for you to figure out are how to synchronize the data (I recommend upsert and External ID fields), and what a reasonable starting number is for your class.
Note that in Spring 15, the ideal method would be a Queueable class, instead, which can repeatedly re-queue itself to process data efficiently without meting out an allotment of counter tokens (like this method does).
Also, if your service provides the number of pending records via some mechanism, you can call for that data in your "start" method with a callout, then adjust the counter accordingly. This would be more efficient and reduce the need/want for suicide batch processes.