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

Не всегда резолвится промис #12

Open
monolithed opened this issue Jul 26, 2015 · 28 comments
Open

Не всегда резолвится промис #12

monolithed opened this issue Jul 26, 2015 · 28 comments

Comments

@monolithed
Copy link
Contributor

При невыясненных обстоятельствах у меня бывают случаи когда промис не резолвится.

tarantool.insert(...)
    .then(result => { /* Не вызывается */  })
    .catch(error => { /* Не вызывается */  })

При этом, записи в базу добавляются.

Бегло нашел множество мест где как мне кажется такое возможно, например
Возможно из-за того, что условие в этом месте может не выполниться

PS: Кстати, почему бы не заменить vow на стандартные Promise, которые уже есть в ноде?

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

Понял, гляну.
PS: Перепишу.

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

Нету еще каких-то подробностей новых?

@monolithed
Copy link
Contributor Author

Повторяется стабильно.
У меня вызов операции insert завернут в десяток других промисов, но как они могут влиять на поведение не понимаю.

Весь код транслируется из ES6 через babel-node

// ... Куча промисов
// .. Тут стоит метка профайлера с логом
tarantool.insert(...)
    .then(result => { /* Не вызывается */  })
    .catch(error => { /* Не вызывается */  })
// .. Тут стоит метка профайлера  с логом 
// Данные в базу добавляются, 100%

Операцию insert выполняю в цикле из более чем 3000 итераций без каких-либо задержек (хотя я пробовал добавлять один элемент, колбек также не сработал).

Если вызвать insert отдельно от моего кода, то все работает.

Структура индексов такая:

return function (space)
    local name, city, host, rank, rate =
        1, 2, 3, 4, 5

    space:create_index('primary', {
        parts = {
            name, 'str',
            city, 'str'
        }
    })

    space:create_index('secondary', {
        type = 'tree',
        unique = false,
        parts = {
            host, 'str',
            rank, 'num',
            rate, 'num',
        }
    })
end

Пример массива данных:

[
    'google.com', 
    'Mountain View', 
    'google.com', 
    100, 
    2000, 
    [
          'YouTube',
          'Nest Labs',
          'FeedBurner', 
          'Songza'
    ],
    'Technologies'
]

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed а что значит 3000 операций? Ты их паралельно записываешь через Promise.all или последовательно?
Понял ща проверю 10к записей подобных что будет.

@monolithed
Copy link
Contributor Author

Я получаю данные, затем в Promise.all мне приходит массив из 3000 элементов, затем в цикле я последовательно выполняю операцию вставки.
Все элементы попадают в базу, но зарезолвить их не получается (

@monolithed
Copy link
Contributor Author

Дебажить мне это дело очень проблематично, потому что код сперва транслируется препроцессором и брейкпоинты теряются.

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed а эти данные совпадают для #11 ?

@monolithed
Copy link
Contributor Author

Данные те же, но там проблема пока ушла.

@monolithed
Copy link
Contributor Author

Вот часть кода, который отвечает за вставку данных:

/**
 * Устанавливает соединение с сервером приложения Tarantool
 *
 * @return {Promise}
 */
get connection () {
    return new Promise((resolve, reject) => {
        this.config.then(({ host, port, user, space_id }) => {
            let tarantool = new Tarantool({ host, port });

            // Прокидываем space_id в инстансе для комфортного доступа
            tarantool.space_id = space_id;

            tarantool.connect()
                .then(status => {
                    return tarantool.auth(user.name, user.password);
                })
                .then(status => {
                    resolve(tarantool);
                })
                .catch(error => {
                    reject('Failed to connect with Tarantool');
                })
            ;
        }, reject);
    });
}


/**
 * Записывает переданные данные в базу
 *
 * @param {Object} tarantool — Ссылка на открытое соединение
 * @param {Object} data — Данные фермы
 * @param {boolean} replace — Использовать операцию "replace"
 * @see normalize
 * @return {Promise}
 */
insert (tarantool, data, replace) {
    let tuple = this.normalize(data);

    return new Promise((resolve, reject) => {
        this.validate(tuple)
            .then(status => {
                let operation = replace ? 'replace' : 'insert';

                tarantool[operation](tarantool.space_id, tuple)
                    .then(resolve, error => {
                        Log.error('Insert operation error:',
                            error.message, '\n', tuple);

                        reject(error);
                    })
                ;
            })
            .catch(error => {
                Log.error('Validation error:',
                    error.message, '\n', tuple);

                reject(error);
            })
        ;
    });
}

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed

[
    'google.com', 
    'Mountain View', 
    'google.com', 
    100, 
    2000, 
    [
          'YouTube',
          'Nest Labs',
          'FeedBurner', 
          'Songza'
    ],
    'Technologies'
]

вот конкретно этот кусок данных 10к раз вставленных отрабатывает но видимо там есть куски гораздо больше или как-то msgpack не справляется с дешифровкой или я где-то не правильно мержу куски данных или неправильно читаю их.

А сам по себе тарантул об ошибках не сообщает?

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed хотя я не правильно сделал ща еще раз поправлю.
Вот когда поправил такая же байда. Это хорошо, теперь поисследую что там.
Хотя все равно не воспроизвелось просто оно 11 секунд у меня вставляется :( может и там у тебя где-то стоит таймаут?

@monolithed
Copy link
Contributor Author

А сам по себе тарантул об ошибках не сообщает?

Тарантул молчит.

msgpack не справляется с дешифровкой

Хм, а как это должно влиять на резолвинг промиса?

Вот когда поправил такая же байда. Это хорошо, теперь поисследую что там.

Это хорошая новость!

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed так не воспроизвелось все таки. Просто у меня тупит машина, на ней еще всякое веселье крутится ._.
Если msgpack не справится то он не поймет к какому промису оно относится. Там оно по requestId расшифровывает ответ.

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

var dataSample = function(_, x){
                return [
    'google.com'+x,
    'Mountain View'+x,
    'google.com',
    100,
    2000,
    [
          'YouTube',
          'Nest Labs',
          'FeedBurner',
          'Songza'
    ],
    'Technologies'
];
            };
        var arr =[];
        for (var i=0; i<10000; i++)
            arr.push(dataSample(i, i));

Таким образом формирую данные для вставки.

@monolithed
Copy link
Contributor Author

Из-за того что msgpack синхронный?

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed не из-за того что msgpack синхронный, а из-за того что данные какие-то не те вернулись. Ну или просто данные не правильно пришли, к примеру один пакет потерялся в процессе и все считай вся линия чтения в этом потоке нарушена.
Надо бы тоже покрыть этот сценарий какими-нибудь тестами, пока такого варианта не получал потому как в среде с плохой связью и потерянными пакетам не тестировал.

@monolithed
Copy link
Contributor Author

Я пробовал выводить данные, который приходят, они все стандартные, отличий вообще нет, разве что могут быть какие-то юникод-символы.

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed а вот функция this.validate она всегда resolve/reject кидает?
Все данные что собираются сохраняются? Можешь провести какой-то анализ типа стадия сбора, а потом стадия сравнения того что собрано с тем что по итогу вставлено в базу.

@monolithed
Copy link
Contributor Author

Да, я же говорю, что в ее колбек я всегда попадаю:

/**
 * Валидация данных кортежа
 *
 * @param {Array}
 * @return {Promise}
 */
validate (data) {
    return new Promise((resolve, reject) => {
        try {
            let validate = jsen(this.schema);

            validate(data);

            if (validate.errors.length) {
                reject(validate.errors);
            }
            else {
                resolve(validate);
            }
        }
        catch (error) {
            reject(error.message);
        }
    })
}

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed ща в мастер патч накатаю и попробуй с ним посмотреть что тебе в консоле выдастся. Ну или как время удобное будет. Где-то через полчаса залью его.

@monolithed
Copy link
Contributor Author

Слушай, похоже проблема действительно может быть в юникод-символах (тарантул их выводит как знаки вопроса в треугольнике), сейчас в базе таких нет и все промисы зарезолвились!

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed ну давай ща проверю что там с unicode'ом. Просто русских символов хватит?

@monolithed
Copy link
Contributor Author

Эти символы приходят мне "извне", письмо парсится

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed тогда скорее всего проблема в msgpack энкодинге/декодинге тогда лучше посмотреть просто обычный лог ошибок. Он куда-то должен был выкинуть ее по идеи, т.к. сам я ее не перехватываю. Сейчас накатаю чтобы оно в мастере пока писало куда-нибудь в диск ошибки эти кодирования декодирования.

@monolithed
Copy link
Contributor Author

Вот пример битой строки

��рилль

Но я это скопировал из базы, как-то же он туда попал

@monolithed
Copy link
Contributor Author

А вот сейчас даже этими символами все нормализовалось, уже раз 10 сделал экспорт и все Ок!

@KlonD90
Copy link
Contributor

KlonD90 commented Jul 26, 2015

@monolithed я посмотрел вообщем-то в msgpack5 он String просто по сути как bytearray хранит, а читает его исключительно как utf-8 потом, так что желательно все привести к utf-8 перед тем как ложить в базу.

Хотя я чот сам туплю он по дефолту тоже пишет utf-8 для string, который write to buffer.

@KlonD90 KlonD90 closed this as completed Feb 15, 2016
@KlonD90
Copy link
Contributor

KlonD90 commented Jul 14, 2016

Кажется я нашел в чем проблема. Скоро все переделаю и будет новая версия с другими багами ._.

@KlonD90 KlonD90 reopened this Jul 14, 2016
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

2 participants