Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Дедупликация запросов #30

Open
doochik opened this issue Oct 15, 2021 · 4 comments
Open

Дедупликация запросов #30

doochik opened this issue Oct 15, 2021 · 4 comments

Comments

@doochik
Copy link
Contributor

doochik commented Oct 15, 2021

Надо подумать нужна ли из коробки дедупликация запросов.

Вариант 1:

// Готовый враппер uniqBlockDecorator.js

const de = require('descript');

module.exports = block => {
    const UNIQ_BLOCK_ID = Symbol();

    return de.func({
        block: (args) => {
            const { context } = args;
            if (!context[UNIQ_BLOCK_ID]) {
                context[UNIQ_BLOCK_ID] = de.run(block, args);
            }

            return context[UNIQ_BLOCK_ID];
        },
    });
};

const uniqBlock = uniqBlockDecorator(de.func({
    block: () => {
        // в рамках одного de.run этот блок исполнится ровно один раз,
        // все последующие вызовы будут возвращать результат из памяти
    },
});

Вариант 2:
Сделать по умолчанию все блоки с дедупликаций и opt out через options.dedupe === false

Вариант 3:
inmemory cache, но его надо делать в рамках de.run. Похоже на вариант 1, только через более нативный кеш, и решает вопрос с ключами.

@doochik
Copy link
Contributor Author

doochik commented Oct 15, 2021

Я себе могу представить такую теоретическую ситуацию

GET /info - запрос за данными раз
   какая-обработка ответа
      POST /some_data (что-то обновили в данных)
         GET /info  - запрос за обновленными данными два

и вот тут будет неоччевидный баг дедупликации

@doochik
Copy link
Contributor Author

doochik commented Oct 15, 2021

У вариант 1 сейчас есть проблема, что он не учитывает параметры вызова.
Изначально этот вариант писался для конкретного блока без параметров

@eljusto
Copy link

eljusto commented Oct 15, 2021

Я за первый вариант с учётом замечения про параметры вызова. Делать opt out опасно, дедупликация должна быть явно запрошена

@pasaran
Copy link
Collaborator

pasaran commented Oct 18, 2021

Я бы предложил смотреть на дедупликацию как на частный случай кэширования.
То есть, если у блока есть options.key и options.cache, то он кэшируется (а значит и дедуплицируется). Но глобально, навсегда. Если в options.cache подсунуть in-memory кэш, уникальный для каждого запроса, то вот вам и дедупликация.
Что-то типа такого:

const dedupCache = {
    get: function( { key, context } ) {
        if ( context.cache ) {
            return context.cache[ key ];
        }
    },
    set: function( { key, value, maxage, context } ) {
        if ( !context.cache ) { context.cache = {}; }
        context.cache[ key ] = value;
    },
};

А для Лешиной ситуации с /info, /do-something, /info нужен какой-то флаг options.ignore_cache. Если этот флаг есть, то а) кэш игнорится и б) этот флаг передается во все подблоки.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants