Pull to refresh

Comments 8

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

Вы видите "функциональные блоки" "связи" "сервис файл" и говорите что это CFC.

Но отличия Устройств от "функциональных блоков" фундаментальны. Устройства полностью автономны, они не выполняют просто функцию. Они могут жить и выполнять работу даже без связей.

В разделе "VRack2 - Архитектурный бриллиант" я постарался описать, насколько потоковая (функциональная) система отстает от идей в VRack2. VRack2 не просто дает площадку для запуска функциональных блоков - он сам - сервис написанный в концепциях VRack2 и на инструментах VRack2, что как бы намекает, что его концепции куда более состоятельные чем простое CFC.

Очень круто, всегда знал что JS для таких вещей наиболее подходящий инструмент.
Решение впечатляет

По статье - немного не понял пример с сокетом, вроде стандартный сокет взывает коллбэк и на этом все приседания заканчиваются

Обычно если мы работаем с синхронными протоколами, мы используем подобную схему

socket_write($sock, "Последовательность байт протокола");
echo socket_read($sock, 1024); // Пытаемся читать ответ устройства блокирую логический поток

Таким образом мы опрашиваем какое нибудь устройство, которое работает только синхронно, например по RS485/UART/CAN.

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

Нам нужно обернуть в метод через внутреннюю очередь, что бы получить аналогичное поведение.

Если что то непонятно - напишите - разберемся.

Спасибо за отклик. К сожалению люди заходят, видят схемы, объем и убегают думая что это про очередной no/low code сервис, недоходя до сути.

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

/**
 * 
 * @param {Socket} socket 
 * @param {*} request 
 * @param {number} timeout 
 * @returns 
 */
async function rpc(socket, request, timeout = 1000) {
    return new Promise((resolve, reject) => {
        if (!socket.writable) {
            reject(new Error('the socket is not writable'))
            return
        }
        if (socket.timeout) {
            reject(new Error('the socket is busy'))
            return
        }
        socket.setTimeout(timeout, () => {
            socket.setTimeout(0)
            reject(new Error('timeout'))
        })
        socket.on('data', (data) => {
            socket.setTimeout(0)
            resolve(data)
        })
        socket.write(request.data, request.encoding || 'binary', (error) => {
            if (error) {
                reject(error)
                return
            }
            console.log('data sent')
        })
    })
}

Если вы считаете не безопасным то- что одновременно может произойти 2 запроса - то вы можете просто проверить "очередь". Это же просто пример.

Тогда уж если занудничать вам нужно использовать once для подписки на "data", в противном случае у вас будет утечка памяти.

С таймаутами вы тоже перемудрили. Вы вроде как локализуете запрос но при этом используете внутренний таймаут сокета который кстати сделан немного для других вещей. Тут лучше использовать обычный setTimeout.

Если вы считаете не безопасным то- что одновременно может произойти 2 запроса - то вы можете просто проверить "очередь".

Не то чтобы я как-то особым образом считал :), - сделал вывод из Ваших описаний,
про очередь видимо упустил. Тем не менее, если есть такая потребность - лучше локализовать ближе к сокету, - во избежание.

Тогда уж если занудничать вам нужно использовать once для подписки на "data", в противном случае у вас будет утечка памяти.

тут признаю - лоханулся, время позднее было, на коленко в слепую накидал

С таймаутами вы тоже перемудрили. Вы вроде как локализуете запрос но при этом используете внутренний таймаут сокета который кстати сделан немного для других вещей. Тут лучше использовать обычный setTimeout.

Не, не согласен, норм - рабочая тема :).
Для каких других вещей сделан таймаут?
В чём преимущество "обычного"?

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

Не, не согласен, норм - рабочая тема :).Для каких других вещей сделан таймаут?

socket.setTimeout - это таймер бездействия (idle), а не таймер выполнения запроса. Это совсем другой таймер.

Если хотите можно сразу сюда https://t.me/Vrack2Group/

Ну или пишите в личку. Но в телеге пооперативнее будет

Sign up to leave a comment.

Articles