Home
Objective Caml
ocaml@conference.jabber.ru
Суббота, 1 августа 2009< ^ >
f[x] установил(а) тему: Камль -- http://caml.inria.fr | Логи -- http://chatlogs.jabber.ru/ocaml@conference.jabber.ru/ | Верблюды грязи не боятся!
Конфигурация комнаты

GMT+4
[00:19:58] <ygrek> что за конфа?
[00:23:12] ygrek вышел(а) из комнаты: I'm leaving this harbour
[00:29:35] <ermine> админская
[00:38:41] gds знал.
[02:28:05] sevenov вошёл(а) в комнату
[02:32:42] sevenov вышел(а) из комнаты: Replaced by new connection
[02:32:44] sevenov вошёл(а) в комнату
[04:22:46] sevenov вышел(а) из комнаты
[04:23:58] sevenov вошёл(а) в комнату
[04:28:11] sevenov вышел(а) из комнаты: Replaced by new connection
[04:28:13] sevenov вошёл(а) в комнату
[08:40:16] sevenov вышел(а) из комнаты
[15:24:39] <ermine> gds: тебе не приходилось решать задачи, в которых надо поменять на ходу функции работы со сокетом, например, открыв сокет обычными функциями для работы с каналами или из Unix модуля, пописать туда и почитать ими же, а потом передать сокет другой библиотеке, чтобы например включить tls?
[15:25:23] <ermine> пытаюсь понять как строить такой апи с использованием модулей или функторами, чтобы на ходу можно было поменять модуль транспорта
[15:26:07] <ermine> основной модуль объявлен как module M (T: Transport) = struct ... end
[16:01:23] sceptic вышел(а) из комнаты
[16:20:04] sevenov вошёл(а) в комнату
[16:32:10] <gds> ermine: именно такое не делал. сразу скажу, что со входными канальями такое не выйдет, ибо буфер там. (выходные можно flush + fd_of_channel.)
Подобное апи на функторах строить стрёмно, так как они слишком статические. Видимо, рулит подход ocamlnet -- объедкты. Ну или вариант с записями, что менее гибко.
[16:34:34] <ermine> у каналов можно получить fd
[16:35:21] <gds> можно, если была бы гарантия того, что в его буфере пусто на момент получения fd.
[16:35:40] <ermine> а мне вот нужна возможность на ходу завоначивать канал/сокет в tls или zlib без перекоткрытия сокета
[16:35:42] <gds> с выходными каналами это можно обеспечить. со входными -- никак.
[16:36:16] <gds> бери ocamlnet-овский вариант с объектами.
функторы -- рассказал, почему не ок.
[16:36:41] <ermine> можно использовать буфферные заворачивалки канала, но для этого надо на ходу поменять read/write функции
[16:37:21] <gds> чото я плохо рассказываю :[
[16:37:54] <ermine> объекты?
[16:38:06] <ermine> а как в объектах поменять на ходу методы?
[16:39:12] <ermine> втупую задача решается просто - передавать либле функции чтения/записи как аргументы
[16:39:16] <gds> зачем менять -- вернуть другой объект и всё. или в реф завернуть.
либо делать запись с мутабельными полями.
[16:39:59] <ermine> в ref, дааа
[16:40:01] <ermine> ы
[16:41:01] <ermine> жалко что ocaml-ssl не умеет tls
[16:41:26] <gds> можно конечно с помощью records + closures эмулировать "приватные члены объектов". смотри, может пригодится.
[16:41:35] <gds> а tls vs ssl -- разница большая?
[16:43:03] <ermine> не очень большая, ssl - открыть сокет сразу в ssl режиме, а в tls можно перейти после обмена нешифрованным трафиком по этому сокету
[16:43:25] <ermine> метод называется STARTTLS
[16:43:29] <gds> может дописать туда tls?
[16:46:21] <ermine> если там найдется функция, которая принимает в качестве аргумента уже действующий сокет, что вряд ли
[16:46:47] <gds> это что ли биндинги поверх имеющейся libssl какой-нибудь?
[16:48:04] <ermine> обычный биндинг к openssl, только непрямой биндинг - в смысле функции openssl не являются external-функциями в камле
[16:48:24] <ermine> в ocaml-ssl код, работающий с openssl
[16:48:34] <ermine> ковырять лениво
[16:48:40] <gds> понял. а какая-нибудь libtls есть?
[16:48:54] <ermine> у меня есть свой биндинг, но вот сначала хочу понять как решать задачу
[16:50:16] <ermine> tls позволяет работать как напрямую с сокетом, так и через буферы, в которых только декодирует/шифрует с дополнительным геморроем для программиста
[16:51:56] <ermine> в случае буферов надо строить цепочку использования данных из канала: socket -> обработать буфер -> обработать буфер (результат предыдущей обработки -> парсер
[16:53:28] <ermine> я бы на данном этапе жизни предпочла бы научиться менять на ходу send/read
[16:57:54] <gds> type socket = { mutable send : string -> ofs:int -> len:int -> unit ; mutable recv : string -> ofs:int -> len:int -> int };
[17:03:49] <ermine> ыгы, придется переделать модуль транспорта
[17:08:08] <gds> а у тебя будут "развоплощения" однажды завёрнутого сокета?
[17:13:48] <ermine> не поняла
[17:14:06] <ermine> развернуть завернутый - нет, протоколом не предусмотрено
[17:16:03] <gds> тогда вариант с мутабельной записью. но как минимум в приватный тип его оформить.
[17:29:03] sceptic вошёл(а) в комнату
[18:55:23] sevenov вышел(а) из комнаты: Replaced by new connection
[18:55:26] sevenov вошёл(а) в комнату
[20:11:02] sevenov вышел(а) из комнаты
[20:20:47] sevenov вошёл(а) в комнату
[22:41:35] <ermine> gds: я тут подумала, что не нужен мутабельные send/recv - просто модуль transport будет уметь нужные способы транспортирования, и этот вопрос можно совместить с уже задаваемым вопросом насчет autotools
[22:42:08] <ermine> осталось понять, чему равен сокет в функции create (), которая создает структуру, но еще не соединяется с сервером
[22:42:32] <gds> гы, а типизацию продумала? тебя ждёт большое ололо.
[22:43:06] <ermine> пчу?
[22:43:59] <gds> M1.t != M2.t, даже если t одинаковы (но если без специального указание про раввинство типов)
[22:44:03] <ermine> module T = sig type socket val send : socket -> string -> unit end
[22:44:12] <ermine> ничо тут не видно, всё спрятано
[22:45:10] <ermine> и дальше module X (Transport : T) = struct,. end, в которой используются функции из T
[22:45:39] <ermine> идея была подсказана либлой pgocaml
[22:46:46] <ermine> вот интереснее как создать сокет, не коннектясь
[22:47:13] <ermine> видимо придется юзать Unix модуль, там можно создать сокет, не коннектясь
[22:47:20] <gds> создать сокет, не коннектясь -- ну почему бы и нет.
[22:47:42] <ermine> а ты попробуй такое с каналами
[22:47:55] <gds> чо я дебил штоле
[22:48:36] <ermine> это спорный вопрос, кто тут дебил
[22:48:39] <gds> но тут засада есть...
module X(T) -- статически типизированная штука.
понимаешь последствия?
[22:49:15] <ermine> ну да, пусть будет статически слинковано
[22:49:45] <ermine> главное - создать нужный модуль на этапе компиляции, узнав что на месте есть tls и zlib и к ним можно прибиндиться
[22:50:34] <gds> да не только в линковке дело.
Rawsocket.t <> Zlibbedsocket.t, вот в чём дело.
[22:51:29] <gds> функция с типом Rawsocket.t -> something useful не будет работать с Zlibbed.socket.t -> something useful.
[22:51:33] <ermine> а его зачем в X знать?
[22:51:59] <ermine> тут вопрос в другом - X должен знать, что можно менять транспорт
[22:52:46] <ermine> типа такая фича имеется
[22:53:12] <gds> X(T) -- статическая штука. Она есть, она в процессе выполнения программы не меняется. В этом и сила, в этом и фейл. X(T).socket <> X(T').socket.
[22:53:39] <ermine> ну это какой-нить функцией can_tls : bool решать чоль :)
[22:54:10] <gds> типы -- разные!
[22:54:31] <ermine> тип один - fd
[22:54:47] <gds> а как же send/recv?
[22:55:38] <ermine> как-нить
[22:57:15] <ermine> снаружи они не меняются, а вот что внутри них
[22:57:24] <gds> нить не как, обычно.
если у тебя изменения типа происходят в рантайме, сразу отметай функторы к писям собачек.
Если не отметаешь -- покажу, где будет лажа (или обломаюсь, что маловероятно).
[22:58:28] <gds> пойми такую штуку. M1.t в общем случае нихрена не совместим с типом M2.t.
[22:59:22] <ermine> та я знаю
[23:01:14] <gds> гуд. А как собираешься тайпчекать выражение вида
if предложили_tls then начать_Transport_tls.начать .. else обработать_дальше ..
?
[23:02:01] <ermine> нее
[23:02:44] <ermine> if поддерживаем t TLS then turn_on t TLS
[23:04:06] <ermine> ну Transport.tunr_on
[23:04:11] <ermine> модуль не меняется
[23:04:40] ermine уже думает о том, как сделать этот самый turn_on
[23:04:48] <ermine> надо позырить в исходники
[23:05:16] sceptic вышел(а) из комнаты
[23:08:20] <gds> и какой тип будет иметь turn_on (или что там стоит в then)?
диавол в мелочах. если надо, предостерегу от ненужного кода посредством анализа мелочей.
лечу по коду!111
[23:08:55] <ermine> неверный вопрос, надо спросить что в этом самом t
[23:09:16] <gds> одно из другого.
[23:09:35] <ermine> поскольку tls и zlib все равно биндинги к С, то ихние структуры можно оставить в цэ
[23:10:15] <ermine> только это не очень хорошо
[23:10:42] <ermine> вон посмотри как строится канал в камле - там структура развесистая
[23:10:56] <ermine> на случай использования и неиспользования тредов, в том числе
[23:12:06] <ermine> так что t может иметь тип { fd : file_descr, tls: Tls.t option; zlib: Zlib option }
[23:12:16] <ermine> Zlib.t
[23:14:32] <ermine> только тип fd сосет
[23:14:35] <gds> говно, щитаю. 1. вопросы компиляции -- решать статически (компилировать или нет данный код). 2. вопросы рантайма (предложили ли tls, zlib или оба вдруг сразу) -- решать в рантайме. closures, records, objects.
[23:15:17] <ermine> type t = Plain fd | TLs fd | Zlib fd :)
[23:15:31] <ermine> и даже | NoneOf
[23:17:00] <ermine> это меньшее говно чем в случае рекорда с оптионалами
[23:17:04] <gds> type t = ref (Plain | TLS | Zlib), скажем прямо. Если ещё не распростилась с мыслью обновления send/recv прямо в значении.
[23:17:16] <gds> конечно, говно сильно меньшее.
[23:17:41] <ermine> а зачем ref?
[23:18:06] <gds> так вроде менять его хотела. не?
[23:18:51] <ermine> ым, да
[23:20:19] ermine загрустила
[23:23:18] <gds> если не будет здоровенных структур данных, на которые ссылается сокет, то можно и мутабельный. будет чотко. приватный тип и внутренняя функция
type socket = { mutable send : ... ; mutable recv : ... }
val tls_wrap : socket -> socket
val zlib_wrap : socket -> socket
и кагбэ всё.
[23:23:37] <gds> ermine: ПИШИ @ КОМПИЛЯЙ
[23:26:55] <ermine> а чему оно равно в функции create ()?
[23:34:29] <gds> уж как определишься. окамл -- язык универсальный. хоть фортраном на нём пешы.
любое create () сокета я бы начинал с нормального сокета, чистого, девственного. но если берёшь разные модули (которые сделаны разными функторами), то тип сокета будет другой и несовместимый.
[23:34:40] <gds> .. с тем, который создаёшь.
[23:36:37] <ermine> ик
[23:39:23] <gds> ок!1111122233
[23:39:47] <ermine> чо пьешь?
[23:40:13] ermine щас распробует рекордину
[23:41:46] <gds> пиво, бехеровка (моя прелесссть!), водка в смесях, рисовый супчик.
рекордину погуглю.
[23:43:11] <ermine> чо, прям сейчас все это пьешь?
[23:44:21] <gds> я про те вещества, которые оставили след на уме, не стёртый GC.
рекордина не гуглится, интересненько.
[23:45:52] <ermine> как же лениво переписывать каналы на сокеты
[23:46:22] <ermine> тот тестовой модуль Transport использовал каналы или pervasives, или lwt
[23:47:05] <ermine> а в create () брались каналы stdio и stdin
[23:47:49] <ermine> еще надо помнить про экспшн EINTR или как иво
[23:48:02] <gds> нуу. кушай статическую типизацию. операции разные по сути => типы разные. оттуда и говно.
[23:48:38] <gds> EINTR -- да, если самостоятельно чтишь сокет.
[23:49:13] <gds> или EWOUDBLOCK.. не помню. Тут мне компилятор рассказывает. Справочники не изучаю.
[23:50:20] <ermine> EINTR оно
[23:50:40] <ermine> неожиданный интерупт
[23:50:57] <gds> да прям шокирующий.
[23:51:46] <ermine> а еще write () надо зацикливать, пока все данные не пропихнешь в сокет
[23:51:56] <ermine> гимарно все это
[23:54:09] <ermine> надо проверить lwt из darcs
[23:56:07] <gds> цикление write -- нормальная история в плане безопасности/надёжности. Под свои требования пишется своя just_write_you_fkd_blch, и вопросы безопасности решаются её изменением.
[23:56:36] <gds> гемор есть, его немало, тут согласен.
[23:59:16] <ermine> а проблема в lwt все же осталась
[23:59:52] <ermine> Sys_error("Socket is not connected")
Powered by ejabberd Powered by Erlang Valid XHTML 1.0 Transitional Valid CSS!