Run more than one async jobs from Future/Quable context

To add on to Phil's answer, what I do before ever invoking a future or a queuable is to reference these utility properties:

public static Boolean   isFutureable {
        get {
            if (isFutureable != null)   {return isFutureable;}  // for testing, permits coercion of value
            if (System.isFuture()) {return false;}  // no future permitted from future
            if (System.isBatch()) {return false;}   // no future permitted from batch
            return Limits.getLimitFutureCalls() - Limits.getFutureCalls() > 0;  // adequate headroom
        }
        set;
    }

public static Boolean   isEnqueueable {

    get {
        return isEnqueueable == null ? Limits.getLimitQueueableJobs() - Limits.getQueueableJobs() > 0 : isEnqueueable;}
    set;
}

Why properties and not methods? So testmethods can coerce a value in order to test out various paths

So,

if (Util.isFutureable) {..call @future method..}
else {
  if (Util.isEnqueueable) { .. System.enqueueJob(..); ...}
  else {
     System.schedule(...) // some fallback job  to get us going again 
                          // (although should also check for limits here too)
  }

I won't try to go in Future/Queueable chains, it can get messy.,

What I would do is to break the chain.

Your requirement of save to BigObect can be done by just firing a platform event. Inside the platform event trigger you can save it to the big objects,

We use platform events and big objects to log things, so I am sure about this approach. What platform event gives you is the flexibility to retry.


This limitation specifically applies to future methods:

No more than 0 in batch and future contexts; 1 in queueable context method calls per Apex invocation

The solution is to make the initial invocation use a Queueable rather than a future method and to break chains of queuables/futures by alternating the approach if at all possible.

In terms of checking things twice, that should be OK as long as you have a common piece of code used in both contexts.