/**
 * User code can invoke remote actors by first obtaining an {@link IPortal} instance (like {@link RemotePortal} or
 * {@link localinvocation.LocalPortal}) and then obtaining a local actor proxy by means of {@link IPortal.retrieve}.
 *
 * The default {@link IPortal} implementation, {@link RemotePortal}, has a reference to an {@link IRemote} to
 * perform the actual remote action calls (via {@link IRemote.invoke}). It converts the method calls on the
 * proxy objects to an {@link IInvokeOptions} object with an {@link IActorCallRequest} as content, then
 * performs the call via {@link IRemote.invoke}, awaits the answer (which is an {@link IInvokeResult} with an
 * {@link IActorCallResponse} as content), and returns the {@link IActorCallResponse.result} or throws an
 * {@link ApplicationError} (when the remote actor threw an exception) or a {@link FrameworkError} when the request
 * could not be complete due to technical causes.
 *
 * ## Backoff mechanism
 *
 * In order to handle short-living network issues and actor reincarnation without having to bother the user code
 * with that, the {@link RemotePortal} repeatedly retries to invoke the remote actor with certain time
 * intervals. This backoff mechanism is provided by an {@link IBackOff} instance like {@link ExponentialBackOff},
 * which provides a backoff with exponentially increasing delays.
 *
 * ## Actor placement
 *
 * In order to know to which destination (app) an {@link IActorCallRequest} should be sent to, the {@link RemotePortal}
 * uses the {@link IActorPlacement} information it receives via the {@link RemotePortal.addMapping} and {@link RemotePortal.removeMapping} methods.
 *
 * ## Local (in process) use
 *
 * For local use (that is, when all code and actors live in the same process), see module {@link localinvocation}.
 *
 * @packageDocumentation
 */
import { IActorPlacement, IBackOff, IPortal, IRemote, ITypedPortal, IAbortable } from '@darlean/base';
import { Aborter, ITime } from '@darlean/utils';
/**
 * Implementation of {@link ITypedPortal} that returns instances of a specific type
 * from a given portal.
 */
export declare class TypedPortal<T extends object> implements ITypedPortal<T> {
    protected portal: IPortal;
    protected type: string;
    /**
     *
     * @param portal The portal from which instances are to be retrieved
     * @param type The type of actors of which instances are to be retrieved
     */
    constructor(portal: IPortal, type: string);
    retrieve(id: string[]): T & IAbortable;
    prefix(idPrefix: string[]): ITypedPortal<T>;
}
/**
 * Implementation of {@link IBackOff} that starts with an initial delay, which is
 * multiplied with a certain factor after every invocation. A spread of 50% is
 * applied to achieve (pseudo)random behaviour.
 */
export declare class ExponentialBackOff implements IBackOff {
    protected time: ITime;
    protected factor: number;
    protected initial: number;
    constructor(time: ITime, initial: number, factor: number);
    begin(maxDurationMS?: number): (aborter?: Aborter) => Promise<boolean>;
}
/**
 * Implementation of {@link IBackOff} that returns immediately (that is, effectively
 * no backoff/delay).
 */
export declare class ImmediateBackOff implements IBackOff {
    begin(_maxDurationMS?: number): () => Promise<boolean>;
}
/**
 * Used to keep administration of which actor type is present on which
 * destinations, and what the current placement settings are for the actor type.
 */
export interface IActorTypeInfo {
    destinations: string[];
    placement?: IActorPlacement;
}
export interface IActorRegistry {
    findPlacement(type: string): IActorTypeInfo | undefined;
}
export declare class ActorRegistry implements IActorRegistry {
    protected mapping: Map<string, IActorTypeInfo>;
    constructor();
    addMapping(actorType: string, receiver: string, placement?: IActorPlacement): void;
    removeMapping(actorType: string, receiver: string): void;
    removeReceiver(receiver: string): void;
    findPlacement(type: string): IActorTypeInfo | undefined;
    getAll(): Map<string, IActorTypeInfo>;
}
export interface IPlacementCache {
    get(actorType: string, id: string[]): string | undefined;
    put(actorType: string, id: string[], receiver: string | undefined): void;
}
export declare class PlacementCache implements IPlacementCache {
    private items;
    private capacity;
    constructor(capacity: number);
    get(actorType: string, id: string[]): string | undefined;
    put(actorType: string, id: string[], receiver: string | undefined): void;
    protected cleanup(): void;
}
/**
 * Portal that provides access to actors in other apps via an {@link IRemote} instance.
 */
export declare class RemotePortal implements IPortal {
    protected remote: IRemote;
    protected backoff: IBackOff;
    protected registry: IActorRegistry;
    protected placementCache?: IPlacementCache;
    constructor(remote: IRemote, backoff: IBackOff, registry: IActorRegistry, placementCache?: IPlacementCache);
    setRegistry(value: IActorRegistry): void;
    retrieve<T extends object>(type: string, id: string[]): T & IAbortable;
    typed<T extends object>(type: string): ITypedPortal<T>;
    prefix(idPrefix: string[]): IPortal;
    protected findReceivers(actorType: string): string[];
    protected iterateDestinations(type: string, id: string[], info: {
        suggestion: string | undefined;
    }): Generator<string, void, unknown>;
}
export declare class PrefixPortal implements IPortal {
    private parent;
    private idPrefix;
    constructor(parent: IPortal, idPrefix: string[]);
    retrieve<T extends object>(type: string, id: string[]): T & IAbortable;
    typed<T extends object>(type: string): ITypedPortal<T>;
    prefix(idPrefix: string[]): IPortal;
}
export declare class PrefixTypedPortal<T extends object> implements ITypedPortal<T> {
    private parent;
    private idPrefix;
    constructor(parent: ITypedPortal<T>, idPrefix: string[]);
    retrieve(id: string[]): T & IAbortable;
    prefix(idPrefix: string[]): ITypedPortal<T>;
}
