/*!
 * IMQLock implementation
 *
 * I'm Queue Software Project
 * Copyright (C) 2025  imqueue.com <support@imqueue.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * If you want to use this code in a closed source (commercial) project, you can
 * purchase a proprietary commercial license. Please contact us at
 * <support@imqueue.com> to get commercial licensing options.
 */
import { ILogger } from '@imqueue/core';
export type AcquiredLock<T> = T | boolean;
export type IMQLockTask = [(...args: any[]) => any, (...args: any[]) => any];
export type IMQLockQueue = Array<IMQLockTask>;
export interface IMQLockMetadataItem {
    className: string;
    methodName: string | symbol;
    args: any[];
}
export interface IMQLockMetadata {
    [key: string]: IMQLockMetadataItem;
}
/**
 * Class IMQLock.
 * Implements promise-based locks.
 *
 * @example
 * ~~~typescript
 * import { IMQLock, AcquiredLock } from '.';
 *
 * async function doSomething(): Promise<number | AcquiredLock<number>> {
 *     const lock: AcquiredLock<number> = await IMQLock.acquire<number>('doSomething');
 *
 *     if (IMQLock.locked('doSomething')) {
 *         // avoiding err handling in this way can cause ded-locks
 *         // so it is good always try catch locked calls!
 *         // BTW, IMQLock uses timeouts to avoid dead-locks
 *         try {
 *             // this code will be called only once per multiple async calls
 *             // so all promises will be resolved with the same value
 *             const res = Math.random();
 *             IMQLock.release('doSomething', res);
 *             return res;
 *         }
 *
 *         catch (err) {
 *              // release acquired locks with error
 *             IMQLock.release('doSomething', null, err);
 *             throw err;
 *         }
 *     }
 *
 *     return lock;
 * }
 *
 * (async () => {
 *     for (let i = 0; i < 10; ++i) {
 *         // run doSomething() asynchronously 10 times
 *         doSomething().then((res) => console.log(res));
 *     }
 * })();
 * ~~~
 */
export declare class IMQLock {
    private static acquiredLocks;
    private static queues;
    private static metadata;
    /**
     * Deadlock timeout in milliseconds
     *
     * @type {number}
     */
    static deadlockTimeout: number;
    /**
     * Logger used to log errors which appears during locked calls
     *
     * @type {ILogger}
     */
    static logger: ILogger;
    /**
     * Acquires a lock for a given key
     *
     * @param {string} key
     * @param {(...args: any[]) => any} [callback]
     * @param {IMQLockMetadataItem} [metadata]
     * @returns {AcquiredLock}
     */
    static acquire<T>(key: string, callback?: (...args: any[]) => any, metadata?: IMQLockMetadataItem): Promise<AcquiredLock<T>>;
    /**
     * Releases previously acquired lock for a given key
     *
     * @param {string} key
     * @param {T} value
     * @param {E} err
     */
    static release<T, E>(key: string, value?: T, err?: E): void;
    /**
     * Returns true if given key is locked, false otherwise
     *
     * @param {string} key
     * @returns {boolean}
     */
    static locked(key: string): boolean;
}
