Ситуация следующая:
Есть интерфейс объекта. Нужно определить существует ли на самом деле этот объект или то приложение с объектом уже умерло. Определить это нужно не дергая за методы интерфейса, потому что приложение может повиснуть (элементарное while(1); ) и тогда мы тоже повисним на этом вызове.
Заранее спасибо!
Здравствуйте Mr_First, Вы писали:
MF>Ситуация следующая: MF>Есть интерфейс объекта. Нужно определить существует ли на самом деле этот объект или то приложение с объектом уже умерло. Определить это нужно не дергая за методы интерфейса, потому что приложение может повиснуть (элементарное while(1); ) и тогда мы тоже повисним на этом вызове.
А если передать этот указатель другому (третьему) объекту. Я так понимаю, что процесс маршаллинга сможет как-то определить жив ли stub или уже нет.
Как такая идея? Или оно плясать будет от прокси клиента?
Vi2>А если передать этот указатель другому (третьему) объекту. Я так понимаю, что процесс маршаллинга сможет как-то определить жив ли stub или уже нет.
Не а. Только при анмаршалинге и то не факт — надо проверять. При маршалинге по моему даже прокся не поднимается.
Здравствуйте Tom, Вы писали:
Tom>Не а. Только при анмаршалинге и то не факт — надо проверять. При маршалинге по моему даже прокся не поднимается.
Анмаршалинг тоже не помогает.
Поясню еще немного ситуацию, может кто-то в этом увидит что то не ладное.
Есть COM-объект SessionManager. Ему в метод Logon приходит интерфейс IClientCallback. Здесь создается объект Session, в который засовывается замаршаленный интерфейс IClientCallback (ну раз замаршалили, то соответственно суем IStream).У Session есть метод get_ClientCallback([out] IClientCallback** ppiClientCallback), в котором интерфейс размаршаливается и возвращается выходным параметром.
Есть еще один класс CGarbageCollector, который крутится в своем потоке. Он берет Session, у него вызывает метод get_ClientCallback, а тот возвращает S_OK в любом случае, даже если клиент уже отвалился (это про то, о чем писал Tom).
Я еще пробывал такой вариант.
CGarbageCollector запускал еще один поток, в котором вызывался метод интрефейса IClientCallback. Если объект не существует, то все ок...метод возвращал ошибку и сборщик мусора убивал эту сессию. А вот если клиент повисший (преславутый while(1), то созданный поток подвисает. Сборщик мусора ждет окончание выполнения данного потока в течении таймаута, по истечении которого он терминирует этот поток....Казалось бы все ок, НО....когда поток подвисает на вызове, он отедает 3-5 хэнделов (смотрел через TaskManager). При терминировании потока эти хэнделы ест-но не освобождаются, что не допустимо....
Щас буду пробывать вариант Vi2....
Какие еще будут мысли на этот счет?!?!
Здравствуйте Vi2, Вы писали:
Vi2>А если передать этот указатель другому (третьему) объекту. Я так понимаю, что процесс маршаллинга сможет как-то определить жив ли stub или уже нет.
Vi2>Как такая идея? Или оно плясать будет от прокси клиента?
Такой вариант не проканал.... Метод этого третьего объекта всегда возвращает S_OK
MF> Я еще пробывал такой вариант. MF>CGarbageCollector запускал еще один поток, в котором вызывался метод интрефейса IClientCallback. Если объект не существует, то все ок...метод возвращал ошибку и сборщик мусора убивал эту сессию. А вот если клиент повисший (преславутый while(1), то созданный поток подвисает. Сборщик мусора ждет окончание выполнения данного потока в течении таймаута, по истечении которого он терминирует этот поток....Казалось бы все ок, НО....когда поток подвисает на вызове, он отедает 3-5 хэнделов (смотрел через TaskManager). При терминировании потока эти хэнделы ест-но не освобождаются, что не допустимо....
Так проблема тут не в валидности интерфейса, а в том что клиент виснет . Если клиента исправить нельзя, то тогда только по таймауту и только с потерей хенделов (если нельзя вывести клиента из while(1)), или после определения того, что произошёл тайм аут, как то корректно убивать клиента. Можно канечно извратиться типа приостанавливать поток, потом подсовывать ему код корректного выхода и запускать снова, но это точно изврат и не так просто.
ЗЫ: Мне кажется, что это проблемма не ком, а структуры приложения.
Здравствуйте Tom, Вы писали:
Tom>ЗЫ: Мне кажется, что это проблемма не ком, а структуры приложения.
Клиент тестовый, в нем специально есть while(1). А задача написать хороший сервер, что бы он мог работать даже с такими клиентами.
У меня была идея на счет RPC. Т.е. отменить подвисший потом средствами RPC...уже все ее функции перерыл ничего путного не нашел. Может кто-нибудь плотно работал с RPC?!?!
MF> Клиент тестовый, в нем специально есть while(1). А задача написать хороший сервер, что бы он мог работать даже с такими клиентами.
О. Идея. А если вызывать методы клиента из отдельного процесса. Если клиент подвис, то ты просто определяешь это и самолеквидироваться ? Или ещё круче. Каждая клиентская сессия в своём процессе, а GC в синглетоне ?
Здравствуйте Mr_First, Вы писали:
MF>Ага...это будет такой монстр, который все свое время будет тратить только на создание отдельных процессов и межпроцесное взаимодействие
Ну если у тебя такие огромные маштабы, то без MTS тебе не обойтись это во первых. Во вторых если ты хочешь и что бы и волкеи сыты и овцы целы, то пиши ручками прокси/стаб для своего CallBack интерфейса или вообще для нотификации не используй ком и пиши всё ручками на сокетах.
Здравствуйте Mr_First, Вы писали:
MF>Привет всем!!!
MF>Ситуация следующая: MF>Есть интерфейс объекта. Нужно определить существует ли на самом деле этот объект или то приложение с объектом уже умерло. Определить это нужно не дергая за методы интерфейса, потому что приложение может повиснуть (элементарное while(1); ) и тогда мы тоже повисним на этом вызове.
А что мешает сделать асинхронный вызов?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.