// Path: src/main/java/com/sulaco/fuse/akka/message/FuseInternalMessage.java
// public interface FuseInternalMessage extends FuseOriginChain {
//     
//     FuseMessageContext getContext();
// 
//     long getRequestId();
// 
//     long getTimestamp();
// 
//     FuseInternalMessage timestamp();
// }
// 
// Path: src/main/java/com/sulaco/fuse/config/ConfigSource.java
// public interface ConfigSource {
// 
//     public void parseLocalConfig();
//     
//     public Config getConfig();
//     
//     public RoutesConfig getRoutesConfig();
// }
// 
// Path: src/main/java/com/sulaco/fuse/config/actor/ActorFactory.java
// public interface ActorFactory extends ActorSystemAware, ApplicationContextAware {
// 
//     public Optional<ActorRef> getLocalActor(String actorClass);
//     
//     public Optional<ActorRef> getLocalActor(String actorClass, String actorName);
//     
//     public Optional<ActorRef> getLocalActor(String ref, String actorClass, int spinCount);
//     
//     public Optional<ActorRef> getLocalActor(String ref, String actorClass, String actorName, int spinCount);
//     
//     public Optional<ActorRef> getLocalActorByRef(String ref);
// 
//     public Optional<ActorSelection> select(String path);
// 
//     public Iterable<ActorRef> getRoutees(String ref, Class<?> clazz, int spinCount);
// 
//     
// }


import akka.actor.ActorSelection;
import com.sulaco.fuse.akka.message.FuseInternalMessage;
import com.sulaco.fuse.config.ConfigSource;
import com.sulaco.fuse.config.actor.ActorFactory;
import com.typesafe.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
package com.sulaco.fuse.akka.async;




@Component
public class RequestSuspenderImpl implements RequestSuspender {

    @Autowired ConfigSource configSource;

    @Autowired ActorFactory actorFactory;

    long sweepInterval;
    long sweepTimeout;

    // Cryo is meant for holding incoming requests in suspended animation, until some unit of work,
    // executed asynchronously, is completed and ready to deliver payload. Upon revival, the payload
    // (if any) will be handed over to appropriate actor (origin or bounce target) and further processing
    // resumes.
    //
    // Cryo will not hold onto these requests forever - there is an active sweeper scanning & terminating
    // requests as necessary. Current version is using a global timeout value (unfortunate).
    //
    NavigableMap<Long, FuseInternalMessage> cryo;


    public void init() {
        initCryo();
        initSweeper();
    }

    void initCryo() {
        cryo = new ConcurrentSkipListMap<>();
    }

    void initSweeper() {
        Config cfg = configSource.getConfig();

        this.sweepInterval = cfg.getLong("fuse.animator.sweep.interval");
        this.sweepTimeout  = cfg.getLong("fuse.animator.sweep.timeout");

        Executors.newScheduledThreadPool(1)
                 .scheduleAtFixedRate(
                         () -> sweepCryo(),
                         0,
                         sweepInterval,
                         TimeUnit.MILLISECONDS
                 );
    }

    @Override
    public void suspend(FuseInternalMessage message) {

        message.timestamp()
// Path: src/main/java/com/sulaco/fuse/akka/message/FuseInternalMessage.java
// public interface FuseInternalMessage extends FuseOriginChain {
//     
//     FuseMessageContext getContext();
// 
//     long getRequestId();
// 
//     long getTimestamp();
// 
//     FuseInternalMessage timestamp();
// }
// 
// Path: src/main/java/com/sulaco/fuse/config/ConfigSource.java
// public interface ConfigSource {
// 
//     public void parseLocalConfig();
//     
//     public Config getConfig();
//     
//     public RoutesConfig getRoutesConfig();
// }
// 
// Path: src/main/java/com/sulaco/fuse/config/actor/ActorFactory.java
// public interface ActorFactory extends ActorSystemAware, ApplicationContextAware {
// 
//     public Optional<ActorRef> getLocalActor(String actorClass);
//     
//     public Optional<ActorRef> getLocalActor(String actorClass, String actorName);
//     
//     public Optional<ActorRef> getLocalActor(String ref, String actorClass, int spinCount);
//     
//     public Optional<ActorRef> getLocalActor(String ref, String actorClass, String actorName, int spinCount);
//     
//     public Optional<ActorRef> getLocalActorByRef(String ref);
// 
//     public Optional<ActorSelection> select(String path);
// 
//     public Iterable<ActorRef> getRoutees(String ref, Class<?> clazz, int spinCount);
// 
//     
// }


// Path: src/main/java/com/sulaco/fuse/akka/async/RequestSuspenderImpl.java
import akka.actor.ActorSelection;
import com.sulaco.fuse.akka.message.FuseInternalMessage;
import com.sulaco.fuse.config.ConfigSource;
import com.sulaco.fuse.config.actor.ActorFactory;
import com.typesafe.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

package com.sulaco.fuse.akka.async;




@Component
public class RequestSuspenderImpl implements RequestSuspender {

    @Autowired ConfigSource configSource;

    @Autowired ActorFactory actorFactory;

    long sweepInterval;
    long sweepTimeout;

    // Cryo is meant for holding incoming requests in suspended animation, until some unit of work,
    // executed asynchronously, is completed and ready to deliver payload. Upon revival, the payload
    // (if any) will be handed over to appropriate actor (origin or bounce target) and further processing
    // resumes.
    //
    // Cryo will not hold onto these requests forever - there is an active sweeper scanning & terminating
    // requests as necessary. Current version is using a global timeout value (unfortunate).
    //
    NavigableMap<Long, FuseInternalMessage> cryo;


    public void init() {
        initCryo();
        initSweeper();
    }

    void initCryo() {
        cryo = new ConcurrentSkipListMap<>();
    }

    void initSweeper() {
        Config cfg = configSource.getConfig();

        this.sweepInterval = cfg.getLong("fuse.animator.sweep.interval");
        this.sweepTimeout  = cfg.getLong("fuse.animator.sweep.timeout");

        Executors.newScheduledThreadPool(1)
                 .scheduleAtFixedRate(
                         () -> sweepCryo(),
                         0,
                         sweepInterval,
                         TimeUnit.MILLISECONDS
                 );
    }

    @Override
    public void suspend(FuseInternalMessage message) {

        message.timestamp()
               .getContext()