31.05.2019, 15:40 | #21 |
Banned
|
Цитата:
Сообщение от KiselevSA
Есть одна, возможно дурацкая, идея:
- в диалоге пользователь указывает полный путь к файлу; - если класс необходимо выполнить в пакетном режиме, в момент создания пакетного задания прикрепить к заданию файл; - в обработке читать прикрепленный файл; - в конце задания удалять прикрепленный файл из хранилища (с диска, из БД и т.п.) |
|
31.05.2019, 18:03 | #22 |
Участник
|
Цитата:
И даже добавил пример импорт Excel. Если честно, я думал, что это очевидно. Чтобы делать обработку на сервере (например, импорт), на сервере должны быть установлены соответствующие библиотеки: Платно-лицензионный Excel, специальные версии .net/dll для бесплатных библиотек, или другие лицензионные продукты (если мы говорим в общем случае). На сервер далеко не всегда можно поставить требуемые обработчики. именно я это я имел в виду под "действия, которые должны быть выполнены на клиенте". Пожалуйста, я постарался сформулировать вопрос предельно точно: RunBaseBatch: как правильно добавить действия, которые должны быть выполнены на клиенте? например, импорт из Excel. |
|
31.05.2019, 18:34 | #23 |
Участник
|
С моей точки зрения "правильно" - это понятие относительное для условий задачи. В одном случае важна скорость разработки, а пользователя можно обучить, в другом надо делать, чтобы быстро работало. В одном случае периодичность пакетного режима нужна - и тогда надо делать очередь доступную с сервера, в другом не нужно (и надо думать как запретить эту периодичность). В одном случае файлы большие, в другом - маленькие.
Что я видел: 1. Отдельный интерфейс для загрузки заданий на сервер, включая использование готовых хранилищ (сетевая папка, встроенный документооборот, ftp, sharepoint) - фактически мы разбиваем на два интерфейса, клиентский и периодическое задание. Это подходит к случаю, когда нам нужна именно периодичность. 2. Загрузка и обработка внутри диалога (например выводим поле в котором сообщение <файл не загружен> и dialog.addMenuItem, на форму/runbase наследника который загружает с прогрессом, возможностью отмены и прочим). Можно сделать отдельную форму подсунуть ее в диалог. 3. Теоретически можно сделать в getFromDialog и бороться с упомянутыми тобой недостатками - вызывать info.yield, WinApi::SetActiveWindow и так далее (я, правда, все это подзабыл) |
|
31.05.2019, 18:53 | #24 |
Участник
|
Цитата:
остальное на твое усмотрение. если ты считаешь "выбешивать пользователя долго висящим диалогом" правильным решением - ок, я понял твои усмотрения. т.е. нет правильного решения для всех случаев? это был мой первый вариант в первом сообщении. Цитата:
В свое время я все на 1Сников наезжал, что они на вопрос "как" постоянно отвечали "можно сделать". Ну, вот настали времена... Ок, расскажите "как правильно добавить действия, которые должны быть выполнены на клиенте (например, импорт из Excel) в современных версиях Аксапты?" должны быть выполнены на клиенте - это не блажь, это реальное условие. Импорт из Excel это всего лишь пример. Ровно как это написано в вопросе.
в общем, ДОЛЖНЫ БЫТЬ выполнены на клиенте. |
|
31.05.2019, 19:13 | #25 |
Участник
|
И да, версии ax3,ax4,ax2009,ax2012 указаны не случайно:
1. в них есть доступ к исходному коду runBase 2. вендор не вносит ломающие изменения в фрейморки |
|
31.05.2019, 20:17 | #26 |
Banned
|
Цитата:
Сообщение от mazzy
Ок, расскажите "как правильно добавить действия, которые должны быть выполнены на клиенте (например, импорт из Excel) в современных версиях Аксапты?" должны быть выполнены на клиенте - это не блажь, это реальное условие. Импорт из Excel это всего лишь пример. Ровно как это написано в вопросе. X++: public boolean runsImpersonated() { // false means that the batch must run on a client. return false; } Цитата:
Running Your Batch on the Client
You have a batch class that overrides the runImpersonated method. The override makes the batch eligible to run only on a client computer. You run a job that schedules the batch. The batch remains in a waiting status until you use the client to tell the AOS to send the client-bound batch to your client now so the batch can run. Но так чтобы серверный RunBaseBatch вызывал клиентский код? В принципе кто запрещает Написать компонент на .NET как сервис на клиентской машине, дергать из Batch сервера по адресу:порту. |
|
|
За это сообщение автора поблагодарили: mazzy (10). |
31.05.2019, 21:08 | #27 |
Участник
|
Цитата:
Сообщение от ax_mct
Правильно так
X++: public boolean runsImpersonated() { // false means that the batch must run on a client. return false; } Не очень понятна фраза "The batch remains in a waiting status until you use the client to tell the AOS to send the client-bound batch to your client now so the batch can run." Спасибо, попробую порыть в этом направлении. |
|
31.05.2019, 21:58 | #28 |
Banned
|
"The batch remains in a waiting status until you use the client to tell the AOS to send the client-bound batch to your client now so the batch can run."
По идее это Basic -> Periodic -> Batch -> Processing запуск чего в клиенте запускает клиентские RunBaseBatch. |
|
31.05.2019, 23:36 | #29 |
Участник
|
Это, фактически, развертывание пакетного сервера на клиентской машине. Соответственно если кто-то с другого клиента назначит пакетное задание, он будет иметь доступ к ресурсам не той клиентской машины с которой его запустили и где был диалог с параметрами, а той на которой крутится пакетный сервер, и, насколько я помню он будет работать под пользователем который запустил пакетный сервер. (На АОСе он запускается под пользователем назначившим пакетное задание).
|
|
|
За это сообщение автора поблагодарили: ax_mct (3). |
31.05.2019, 23:52 | #30 |
Участник
|
Думаю, нет. Практически всегда практически для любого решения так обще поставленной задачи можно придумать случай, когда оно будет неправильным а правильным другое.
Цитата:
Обрати внимание, что вопрос был НЕ "можно ли", а "как"?
|
|
01.06.2019, 00:13 | #31 |
Banned
|
Цитата:
Обрати внимание, что вопрос был НЕ "можно ли", а "как"?
В то время как если упираемся в стенку то как правило дело не в той дороге. |
|
01.06.2019, 13:55 | #32 |
Участник
|
Цитата:
Сначала ответь на поставленный вопрос, потом обзирай. Цитата:
Сообщение от ax_mct
Правильно так
X++: public boolean runsImpersonated() { // false means that the batch must run on a client. return false; } Во-первых, этот метод работает только начиная с 2009, где ввели таски в пакетном задании. Во-вторых, похоже, этот метод требует минимум трех классов: = управляющий класс, который собственно и создает пакетное задание = клиентский класс для выполнения действий на клиенте = серверный класс для выполнения действий на сервере метод runsImpersonated() не решает задачу передачи данных с клиента на сервер. по-прежнему, можно передавать данные через таблицу, создавая тикет для сессии, и занимаясь обслуживанием сессионных данных (удаление устаревших, нумератор сессии, уникальность нумератора в случае отказов и т.п.) Мало того, этот метод сильно усложняет saveLast. Либо я чего-то кардинально не понимаю. Похоже, что для работы не обязательно создавать клиентский пакетник. Хотя и можно. Похоже, что клиентская таска может выполняться сразу после запуска, а не по расписанию.Тут пока много непонятного. Кто-нибудь ходил этим путем? Есть рекомендации? ============ пока вариант с двумя классами и со свойством runOn кажется более простым. там только одна сложность - как передать расписание запуска второму классу и сбросить эти параметры с первого. Последний раз редактировалось mazzy; 01.06.2019 в 14:07. |
|
|
За это сообщение автора поблагодарили: ax_mct (2). |
01.06.2019, 15:56 | #33 |
Banned
|
Цитата:
Если это одна операция и просто нужен код работающий на сервере то это можно и так сделать. В рамках одного и того же RunBaseBatch. Если это несколько операций и у нас есть отдельные независимые RunBaseBatch которые должны быть запущены последовательно то на ум приходит то что называется batch task когда мы ручками создаем строки в Batch tasks и определяем Conditions. Это требует canGoBatchJournal = true и особенностей вызова параметров у RunBaseBatch. Но вот как эти Batch tasks работают с legacy client RunBaseBatch - не знаю. По идее должны. |
|
01.06.2019, 16:51 | #34 |
Участник
|
Цитата:
Что непонятно в исходной формулировке? Что непонятно в исходном вопросе? Цитата:
Сообщение от mazzy
Предположим у нас есть RunBaseBatch.
Он делает что-то тяжелое. Мы конечно же хотим сделать так, чтобы он мог работать на пакетном сервере. Но этот класс забирает данные из какого-нибудь файла, который находится на клиенте. Как и куда правильно вставить действия, которые должны выполняться на клиенте? |
|
01.06.2019, 16:54 | #35 |
Участник
|
оставлю отдельным сообщением:
|
|
02.06.2019, 15:45 | #36 |
Banned
|
Цитата:
Сообщение от mazzy
Предположим у нас есть RunBaseBatch.
Он делает что-то тяжелое. Мы конечно же хотим сделать так, чтобы он мог работать на пакетном сервере. Но этот класс забирает данные из какого-нибудь файла, который находится на клиенте. Как и куда правильно вставить действия, которые должны выполняться на клиенте? Сейчас правильный способ видится таким: * разбить процесс на два runBaseBatch класса: первый будет иметь свойство RunOn=Client, второй - RunOn=Server * первый в методе run должен будет выполнить клиентские действия, создать второй класс на сервере и передать ему параметры и данные Но что-то как-то слишком сложно. Очень напоминает overprogramming. Может существует другой способ? -Но этот класс забирает данные из какого-нибудь файла, который находится на клиенте. -Как и куда правильно вставить действия, которые должны выполняться на клиенте Непонятно почему запуск клиентского RunBaseBatch (оставленный как legacy) когда клиент работает как пакетный сервер не покрывает все три условия. В исходном вопросе непонятно зачем нужен второй RunBaseBatch на сервере. Каким путем? Клиентский пакетник создает серверный пакетник и передает ему параметры и данные? Дык если нужен последующий пакетник то речь об BatchTasks. А если просто вызов серверного кода в том же запуске то о том и речь что пакетник то зачем. Грубо например BlbBlaServer::runOnServer(Args, DataReferenceParmId) Я тупой |
|
02.06.2019, 15:57 | #37 |
Banned
|
Цитата:
А если просто вызов серверного кода в том же запуске то о том и речь что пакетник то зачем.
Грубо например BlbBlaServer::runOnServer(Args, DataReferenceParmId) Прошу прощения. Но тогда передача args на точку входа серверного RunBaseBatch и запуск его без Batch здесь и сейчас мне кажется корректным ответом на вопрос. Данные просто передаются как ссылка на идентификатор в staging или temp. |
|
02.06.2019, 18:03 | #38 |
Участник
|
Можете пояснить за схему?
Клиентский RunBaseBatch работает как в Ax3 - его выполняет ax32 а не ax32serv или как там его, но его надо специально запускать. Он берет задания из указанной пакетной группы, но никто не гарантирует что это та же самая машина где были введены параметры пакетного задания. То есть пользователь может на другой машине ввести локальный путь, пакетное задание попадет в очередь, будет обработано на той машине где запущен клиентский пакетный сервер (он клиент для аоса, но сервер для тех кто ему посылает задания). В этом случае он не может без дополнительных действий воспользоваться параметрами, так как они содержат локальный путь на файл из другой машины. Вы предлагаете: 1. Cоздавать пакетную группу для конкретной клиентской машины, запускать на ней пакетный сервер и административно запретить назначать в нее задания с других клиентских машин? 2. Переписывать файл куда-то, где им можно воспользоваться с другой машины? 3. То же самое, что и 1. только автоматически? 4. Другое? |
|
02.06.2019, 20:59 | #39 |
Banned
|
Цитата:
Как и куда правильно вставить действия, которые должны выполняться на клиенте?
Схема - использовать legacy RunbaseBatch на клиенте. Это имеет указанные вами недостатки но они больше надуманные. И не указаны в условии задачи. А если подразумевать сценарии использования не только на выделенной для этой машине, а потенциально на любой, то уверен что это не проблема. Самое очевидное это копировать файл в сетевую папку. Главное это возможность использовать компоненты не доступные на server OS и использование выделенной машины с desktop OS с запущенным клиентом AX в роли batch server это решает. В старом и привычном для Axapta 3.0 стандарте. |
|
03.06.2019, 12:23 | #40 |
Участник
|
Цитата:
Цитата:
Сообщение от belugin
Клиентский RunBaseBatch .... берет задания из указанной пакетной группы, но никто не гарантирует что это та же самая машина где были введены параметры пакетного задания. То есть пользователь может на другой машине ввести локальный путь, пакетное задание попадет в очередь, будет обработано на той машине где запущен клиентский пакетный сервер (он клиент для аоса, но сервер для тех кто ему посылает задания).
В этом случае он не может без дополнительных действий воспользоваться параметрами, так как они содержат локальный путь на файл из другой машины. |
|
|
За это сообщение автора поблагодарили: mazzy (2), Raven Melancholic (2). |
Теги |
как правильно |
|
|