LINUX.ORG.RU

Как правильно и можно ли сделать proxy объект в R.

 ,


0

2

У меня возникла достаточно странная задача. Мне нужно оборачивать, некоторые объекты (возможно заранее неизвестного типа), в прокси, которое будет передавать их дальше настоящему объекту специальным образом. Если нужен пример, то для простоты, допустим будет логировать то, что имя вызываемой функции и параметры (но на самом деле там логика более сложная). Т.е. в идеале хочется, что-то вроде.

library(RODBC)
myconn <-odbcConnect("mydsn", uid="Rob", pwd="aardvark")
wrapper <- createProxy(myconn)
crimedat <- sqlFetch(wrapper, "Crime")
pundat <- sqlQuery(wrapper, "select * from Punishment")

Чтобы исключить X-Y проблему. На самом деле задача открывать соединение в одном процессе, а делать запросы в другом отфоркнутом от первого (эта часть задачи не обсуждается). Соответственно идеей решения было создать такой прокси объект, в который будет передавать запрос в родительский процесс, там он будет выполняться и получать результат назад. Соответственно вопрос, есть ли тут более адекватные решения данной задачи, чем предложенное и есть ли адекватные способы только на уровне R реализации идеи решения.

★★★★★

Ответ на: комментарий от Evgueni

когда я впервые услышал о том, что эти ребята хотят я тоже подумал про MPI и HPC, но нет, там смысл немного в другом.

Я не знаю могу ли я подробно рассказывать зачем и почему там выбрана такая архитектура, но зная это все выглядит разумно. Если очень грубо, то там нужно вычислить окружение, которое нужно передать в другие процессы, чтобы они дальше уже могли независимо с ним работать. С этим все хорошо, ровно до тех пор, пока пользователь не пытается использовать объекты, которые «ломаются» при форке, например коннект к базе данных. И его нужно или из каждого окружения пересоздавать (что будет дорого по ресурсам) или делать вот такой объект, как предложено выше.

За ссылки в любом случае спасибо, перечитаю, может я что упустил.

qnikst ★★★★★
() автор топика
Ответ на: комментарий от qnikst

Это всё происходит в пределах одной машины или нескольких? Если нескольких, то я слабо себе представляю процедуру перекидывания коннекта с одной машины на другую, точнее слабо представляю осмысленность этого. Если в пределах одной машины, то всегда можно связаться через родителя, который является выделенным процессом и держит так нужный всем коннект.

Evgueni ★★★★★
()
Ответ на: комментарий от Evgueni

Одной машины.

Evgueni

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

Да, именно это я и собирался делать.

Вопрос тут в том, как это сделать максимально прозрачно для пользователя пишущего на R.

Идеальный вариант если он пишет код так, как писал бы не зная об особенностях имплементации, т.е. он бы мог писать sqlFetch(myconn, "Crime") и не думать, что запрос будет исполнять другой процесс, а просто бы получил SEXP на выходе. Правда как это сделать я вообще не вижу, разве что если писать обёртки ко всем библиотекам, что не масштабируется.

Другие варианты так или иначе раскрывают особенности имплементации, например, сделать обёртку над произвольным объектом, которая «будет знать», что запрос нужно передать в другой процесс, тогда нужно в родительском окружении создать эту обёртку и дальше в дочернем пользователь будет использовать её wrapper, а не myconn. В этом случае об особенностях имплементации должен знать только создатель родительского окружения.

Ещё один вариант, о котором я не думал в момент написания вопроса, - ввести обёртку для метода runInParent(call, params..). В этом случае пользователю все же придётся знать об особенностях имплементации, но зато он масштабируется на любые библиотеки и реализуется более-менее понятным образом.

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

qnikst ★★★★★
() автор топика

Распределенный доступ к данным это отдельная тема и делать свой велосипед очень неправильно.

1. Люди пишут специальные файловые поддерживающие параллельное чтение-запись на них наверное не зря? Вместо конекта к базе использовать такую файловую.

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

3. Можно код R положить как сторед процедуру в sql базу к данным. Не понадобятся все эти фантазии с отдельными R форками.

4. Можно соединение с базой держать в одном процессе, а воркеры будут слать запросы туда по очереди сообщений.

psv1967 ★★★★★
()
Ответ на: комментарий от psv1967

1. Completely irrelevant

2. Completely irrelevant

3. Completely irrelevant

4. Про это и вопрос! В том как это организовать максимально прозрачно для пользователя.

Это я так непонятно вопросы формулирую, или кто-то ленится их читать?

qnikst ★★★★★
() автор топика
Ответ на: комментарий от qnikst

1.2.3. Столько людей и корпораций не угодило такому лаконичному человеку, что я позволю себе не поверить.

psv1967 ★★★★★
()
Ответ на: комментарий от psv1967

1,2,3 - все это хорошо и отлично, но не относится к моему вопросу *совершенно* никак. Откуда вы нашли в вопросе что-то про распределенный доступ к данным я боюсь даже предположить. Так что оставьте веру служителям религии, а если хочется побыть полезным в данном треде, то Ваш опыт в отношении 4, был бы действительно интересен (в общем-то во многом именно из-за этого данный вопрос и был написан на лоре).

qnikst ★★★★★
() автор топика
Ответ на: комментарий от qnikst

1. Вы можете _без_ предположений о личности собеседника сказать, _зачем_ Вам соединение к базе? Чем это «зачем» _принципиально_ отличается от замены данных в базе, на данные лежащие в распределенном доступе (для форков) одним из описанных способов?

Если же данные действительно должны лежать в базе, то почему там же не может лежать и код их обрабатывающий?

Оба эти варианта и написали, чтобы не надо было в форки таскать соединения с базами.

У меня складывается впечатление что Вам «не нравиться стук костылей» которыми пользуетесь Вы из лени что либо менять, исправляя ошибки сделанные в архитектуре, или кто то (?начальство?) не разрешает что либо менять проекте.

Я вообще не понимаю какую _пользу_для_меня_ я должен почерпнуть от такого _одностороннего_ (*совершенно*) общения с Вами. Я не вижу у Вас _никакой_ задачи, кроме «как бы ничего не менять».

Зачем например вообще форки то нужны?

2. Указание конкретной очереди сообщений (такая же как и везде — ZeroMQ) передающей объекты ничего не изменит в этом обсуждении, скорее всего начнется обсуждение «какая эта очередь тяжелая».

Никаких готовых «мигрирующих сетевых сокетов» нет.

psv1967 ★★★★★
()
Ответ на: комментарий от psv1967

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

Спасибо, Evgueni за участие. Спасибо и вам за время.

qnikst ★★★★★
() автор топика
Последнее исправление: qnikst (всего исправлений: 1)
Ответ на: комментарий от qnikst

В том как это организовать максимально прозрачно для пользователя.

Написать proxy-объект или открывать новое ODBC-соединение после fork.

сожалею о том, что создавал этот тред..

А всего-то и надо - заигнорить psv1967.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Вот насколько я знаю R (я знаю его внутренности, но совершенно без опыта написания программ на нем), он слишком «процедурный», чтобы чтобы писать proxy обьект. И функция написанная в третьей библиотеке с ним работать не сможет. Поэтому похоже придется писать proxy функцию, которая может просто передать все параметры (функцию которую надо выполнить и аргументы) выше. Но остается шанс, что я чего-то о R не знаю и есть решения лучше или все изобретено до меня.

Я надеялся что psv1967 расскажет мне про то, как сделать прокси обьект или функцию разумным образом, но что-то не взлетело :).

qnikst ★★★★★
() автор топика
Последнее исправление: qnikst (всего исправлений: 1)
Ответ на: комментарий от qnikst

похоже придется писать proxy функцию, которая может просто передать все параметры (функцию которую надо выполнить и аргументы) выше.

Я это и имел в виду.

Еще можно подумать, как бы заманкипатчить функцию fork в стандартной библиотеке R, чтобы создавать в новом процессе новое подключение к БД.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

ага, идею понял. Добавлю, что у меня форкается не R, код, а тот, что вызывает R внутри себя, в принципе я могу из него проинспектировать все переменные. Но я боюсь, что этот подход не будет масштабироваться на разные библиотеки, а их выбирает пользователь (я не контролирую тот R код, который выполняется, в принципе там может быть почти что угодно). В дочерних процессах R урезанный, наверное я там смогу даже автоматически подставлять прокси метод когда нужно.

qnikst ★★★★★
() автор топика
Ответ на: комментарий от psv1967

Наверное, в этом треде может показаться, что я был излишне резок, поэтому теперь, написав работающий proof of concept данного решения, которое меня устраивает на данный момент и добравшись до компьютера я таки отвечу подробно. Извиняюсь, что сообщение будет на грани перехода на личности, и содержит многочисленные повтор одних и тех же утверждений, но все же расставить точки над i стоит.

У меня есть, некоторая задача, полностью, которую описывать я не могу в силу NDA. О чем я написал в самом первом посте, там лишь был дан короткий намёк, на то, что система из себя представляет. И задан вопрос, каким образом наиболее логично и правильно делать в R proxy методы/объекты, которые изменяют поведение фунции нужным мне образом - в данном случае передают её на исполнение worker-у.

Мне бы, конечно, интересно было бы поговорить о разных распределенных файловых системах, например, я знаю что происходит в мире ceph и lustre, и разных проприетарных (и не публичных) решениях поверх них, и всяких проектах вроде http://www.sagestorage.eu/ . Но наверняка, многие из векторов развития от меня ускользают и об этом интересно поговорить, правда тогда, когда нужно решать соответствующие задачи, а не мою.

Пускалки параллельного кода, это тоже интересно, но в данной задаче нету параллельного кода, который исполняется.

Возможности пускать код на R внутри опять же очень интересен и заслуживают отдельного разговора, например, я не знал о таких возможностях. Но опять в данном случае есть программа и в ней есть dsl-ли для анализа данных, один из которых это R, а базы может и не быть. К тому же базы данных могут не принадлежать пользователю или в них может не быть поддержки R.. И это снова какая-то своя задача.

(Замечу, что «идея №4 является переформулировкой идеи решения высказанной в моём вопросе. Именно она и реализуется, позволю себе процитировать „Соответственно идеей решения было создать такой прокси объект, в который будет передавать запрос в родительский процесс, там он будет выполняться и получать результат назад“. И о деталях её имплементации вопрос и был)

Итого, сделано аж 3 предположения, о каких-то своих.. Мне было, искренне, лень распространяться о том, почему это не относится к задаче, и я хотел сфокусироваться на последнем варианте, про который я изначально и спрашивал. Поэтому я написал, что данные предположения к ней не относятся (completely irrelevant), мне кажется специалисту должно было бы быть это понятно, и не очень обидно. Итого, 3 (три!!!) предположения о задаче высказанные в утвердительном тоне, и 1 (одно) повторение того что написано, без понимания того, что это повторение! О каком, простите, одностороннем общении вы говорите?

В целом мне интересно было бы обсудить затронутые темы, но мне бы очень хотелось, чтобы при этом мой собеседник:

1. Если видит, что в задаче идёт разговор о форках процесса, то мог бы и сам понять, что разговор идёт не про распределенную систему.

2. Если видит, что в задаче идёт разговор о форках процесса, то мог бы и сам понять, что речь идёт исключительно про (R/O) чтение окружения созданного в родительском процессе из дочерних.

3. Понимал, что вопрос о том какая конкретная очередь сообщений или сокеты должны использоваться, вообще не может ставиться, а любой адекватный специалист всегда сможет выбрать конкретный вид IPC подходящий для его задачи. (Исключение, если в вопросе явно спрашивают про IPC).

4. Человек умеет читать текст написанный ему и не воспринимает, то что с ним не соглашаются в штыки (тут возможны уступки ибо сам грешен).

5. Человек не делает необоснованных попыток „угадать“, то, о чем намерянно умолчали, а если делает, то хотя бы спросит так ли это. Например, во первым же ответом была попытка угадать, то что мне надо, но прекрасно оформленная.

6. Отлично было бы, чтобы если бы человек заметил, (это правда невозможно по стартовому сообщению, но потом я уточнил), что разговор был про детали имплементации и можно было заметить, что код на R, пишется клиентом, от которого желательно скрыть детали реализации продукта. Т.о. желательно, чтобы клиент мог писать код на R к которому привык и не задумываться, об особенностях платформы. Ведь в противном случае можно просто написать свою простую либу, а программистов легко обучить (ну или уволить).

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

В общем-то я уже не надеюсь на возращение ветки дискуссии в профессиональное русло, но для полноты треда кратно отвечу:

_зачем_ Вам соединение к базе?

чтобы получать данные из таблиц в ней хранящихся, К.О.

Чем это «зачем» _принципиально_ отличается от замены данных в базе, на данные лежащие в распределенном доступе (для форков) одним из описанных способов?

тем, что это «зачем» не изменяет данные, К.О? Плюс первые 3 способа никак не помогают заменить данные в базе, а последний способ это имеено то, что я и реализовывал. Повторю: предложенный вами способ ничем, не отличается от реализуемого мной, поскольку это один и тот же способ. Вопрос же был в том, как его сделать удобным для ничего не подозревающего пользователя, а не какой IPC использовать.

Если же данные действительно должны лежать в базе, то почему там же не может лежать и код их обрабатывающий?

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

Оба эти варианта и написали, чтобы не надо было в форки таскать соединения с базами.

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

У меня складывается впечатление что Вам «не нравиться стук костылей» которыми пользуетесь Вы из лени что либо менять

Тут вы правы, абсолютно не нравится. Но ни времени, ни возможностей переписывать движок R за разумное время ни у меня, ни у компании нету, да и там столько legacy, что написать нормально, практически не реально. К тому же поддержки community, не будет. История знает уже несколько проектов в этом направлении, но ни один из них „не взлетел“. Так что крутимся как есть.

исправляя ошибки сделанные в архитектуре,

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

Я вообще не понимаю какую _пользу_для_меня_ я должен почерпнуть от такого _одностороннего_ (*совершенно*) общения с Вами.

А я вот знал, какую пользу я мог получить от общения с вами. Я не являюсь специалистом в написании „пользовательского“ кода на R и не знаю хороших шаблонов там, и именно об этом я задал вопрос. Вместо ответа на вопрос, возможно с объяснением о том, что не надо так и надо делать все по другому, я получил попытки решения архитектурных проблем от человека, который не знает задачи, и не спрашивает про неё, а что-то выдумывает. Не надо так.

Я не вижу у Вас _никакой_ задачи, кроме «как бы ничего не менять».

Да, я про это писал начиная с первого ответа вам, вы пытаетесь найти какую-то задачу, вместо того, чтобы прочитать про что именно спрашивают. Очередной раз повторяюсь, задача была, „как правильно на R писать proxy объект/метод, меняющий поведение оборачиваемого метода“.

Зачем например вообще форки то нужны?

Зачем не могу сказать :) . Но могу сказать, что именно форки, то мне и нужны всегда, а вот коннект к базе в редких случаях.

Никаких готовых «мигрирующих сетевых сокетов» нет.

Не знаю откуда вы это берёте, ещё и в кавычках, как будто цитата?!

qnikst ★★★★★
() автор топика
Ответ на: комментарий от qnikst

в SEXP часто лежат указатели, так что IPC на них не построить, если же гонять сериализованые обьекты - это уже не про форк. parallel-package - наверное максимум прозрачности сериализации, возможно fork cluster оттуда можно адаптировать под ваши нужды.. но накладные расходы конечно, да..

anonymous
()
Ответ на: комментарий от anonymous

В общем случае - да, но serialize вызывает refhook, если передается поле с указателем. Я про это не говорил, но в форке новые pointed данные не могут создаваться. Таким образом указатель можно просто сериализовать как текст, а на другой стороне получать указатель и создавать SEXP обратно, и он гарантировано будет указывать на правильный объект. refhook у меня FFI, поэтому там такое провернуть просто. Судя по proof of concept коду это даже работает.

qnikst ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.