Обрыв соединения в DCOM
От: Grenal  
Дата: 09.07.01 15:20
Оценка:
Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(
Re: Обрыв соединения в DCOM
От: Аноним  
Дата: 10.07.01 08:02
Оценка:
Здравствуйте Grenal, вы писали:

G>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


Что такое "контекст пользователя"?
DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)
Re[2]: Обрыв соединения в DCOM
От: Grenal  
Дата: 10.07.01 11:36
Оценка:
Здравствуйте Аноним, вы писали:

А>Здравствуйте Grenal, вы писали:


G>>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


А>Что такое "контекст пользователя"?

А>DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
А>Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
А>Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)

Про контекст пользователя. На сервере есть ресурсы, которые пользователь может удаленно захватывать. Ресурсы предоставляет компонент в EXE, который создан как DECLARE_CLASSFACTORY_SINGLETON. Когда пользователь отваливается, он не успевает освободить ресурс и ресурс становится недоступен другим пользователям. Мне приходит в голову только способ при помощи Ping'ов, если типа ping от пользователя не пришел, то его ресурсы можно освобождать. Или может у DCOM есть что-то типа CAsyncSocket::OnClose().

Клиент словит падения прокси при вызове методов последнего, это я понимаю, а вот как мне вычистить ссылки на серверные интерфейсы или их можно просто обнулить и как поступить со сток интерфейсами. И клиент и сервер у меня С++ интерфейсы на базе IUnknown.
Re[3]: Обрыв соединения в DCOM
От: Аноним  
Дата: 10.07.01 12:22
Оценка:
Здравствуйте Grenal, вы писали:

G>Здравствуйте Аноним, вы писали:


А>>Здравствуйте Grenal, вы писали:


G>>>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


А>>Что такое "контекст пользователя"?

А>>DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
А>>Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
А>>Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)

G>Про контекст пользователя. На сервере есть ресурсы, которые пользователь может удаленно захватывать. Ресурсы предоставляет компонент в EXE, который создан как DECLARE_CLASSFACTORY_SINGLETON. Когда пользователь отваливается, он не успевает освободить ресурс и ресурс становится недоступен другим пользователям. Мне приходит в голову только способ при помощи Ping'ов, если типа ping от пользователя не пришел, то его ресурсы можно освобождать. Или может у DCOM есть что-то типа CAsyncSocket::OnClose().


G>Клиент словит падения прокси при вызове методов последнего, это я понимаю, а вот как мне вычистить ссылки на серверные интерфейсы или их можно просто обнулить и как поступить со сток интерфейсами. И клиент и сервер у меня С++ интерфейсы на базе IUnknown.


Про контекст пользователя: Что значит захватывать? Если на все время клиентской сессии, то лучше деражть все ресурсы в несинглтоновском серверном объекте. Тогда это объект умрет, кода умрет его единственная (если не давать его кому-то еще) прокся. Как при корректном ее релизе клиентом, так и, в идеале, при обрыве соединения или некорректной смерти клиента.
Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона

Ненадо ничего специально вычищать — освободи все ссылки, как при нормальном выходе и забутьте о них — заново CoCreateInstance, подписки и т.д.
Re[4]: Обрыв соединения в DCOM
От: Grenal  
Дата: 10.07.01 13:20
Оценка:
Здравствуйте Аноним, вы писали:

А>Здравствуйте Grenal, вы писали:


G>>Здравствуйте Аноним, вы писали:


А>>>Здравствуйте Grenal, вы писали:


G>>>>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


А>>>Что такое "контекст пользователя"?

А>>>DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
А>>>Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
А>>>Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)

G>>Про контекст пользователя. На сервере есть ресурсы, которые пользователь может удаленно захватывать. Ресурсы предоставляет компонент в EXE, который создан как DECLARE_CLASSFACTORY_SINGLETON. Когда пользователь отваливается, он не успевает освободить ресурс и ресурс становится недоступен другим пользователям. Мне приходит в голову только способ при помощи Ping'ов, если типа ping от пользователя не пришел, то его ресурсы можно освобождать. Или может у DCOM есть что-то типа CAsyncSocket::OnClose().


G>>Клиент словит падения прокси при вызове методов последнего, это я понимаю, а вот как мне вычистить ссылки на серверные интерфейсы или их можно просто обнулить и как поступить со сток интерфейсами. И клиент и сервер у меня С++ интерфейсы на базе IUnknown.


А>Про контекст пользователя: Что значит захватывать? Если на все время клиентской сессии, то лучше деражть все ресурсы в несинглтоновском серверном объекте. Тогда это объект умрет, кода умрет его единственная (если не давать его кому-то еще) прокся. Как при корректном ее релизе клиентом, так и, в идеале, при обрыве соединения или некорректной смерти клиента.

А>Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона

А>Ненадо ничего специально вычищать — освободи все ссылки, как при нормальном выходе и забутьте о них — заново CoCreateInstance, подписки и т.д.


Ресурсами выступают поворотные устройства для камер, которые висят на RS232 до 16 штук на одном порту. Все устройства адресуемые, пока пользователь крутит устройством для всех других пользователей устройство блокируется. Но другой пользователь может крутить другим устройством, отсылая команды все в тот же последовательный порт. Серверный ком-объект практически предоставляет интерфейс для работы с шиной управления (порт RS232) для многих пользователей, так что без DECLARE_CLASSFACTORY_SINGLETON не обойтись(последовательный порт-то у меня один и список доступных поворотников тоже один). За одну сессию пользователь может крутить несколькими поворотниками, последовательно их блокируя и разблокируя.

Уважаемый, что значит "Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона", поясните пожалуйста на моем примере.

По поводу вычищения ссылок, действительно, когда сервер и клиент работают на одной машине все происходит по описанному Вами сценарию, но когда я вынимаю сетевой кабель при работе на разных машинах в AtlUnadvise происходит какая-то ошибка сейчас подключу вторую машину и исследую этот вопрос подробней.
Re[5]: Обрыв соединения в DCOM
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.07.01 16:23
Оценка:
Здравствуйте Grenal.

Ваша проблема решается так. Делает отдельный обект. Называете его, к примеру, LockCamera. Когда клиенту нуужно дать контроль над камерой, помещаете информацию о камере в LockCamera и возвращаете пользователю указатель на его интерфейс. Кокда клиенту больше не нужно управление он освобождает ссылку. Ссылка автоматически освобождается если клиент безвременно скончается.

В принципе через такой объект можно организовать и управление камерой.

Скорость создания COM-объектов давольно высокая, к моу же их можно создавать вручную (new), а не чере CoCreateInstance.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Обрыв соединения в DCOM
От: Аноним  
Дата: 10.07.01 16:52
Оценка:
Здравствуйте Grenal, вы писали:

G>Здравствуйте Аноним, вы писали:


А>>Здравствуйте Grenal, вы писали:


G>>>Здравствуйте Аноним, вы писали:


А>>>>Здравствуйте Grenal, вы писали:


G>>>>>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


А>>>>Что такое "контекст пользователя"?

А>>>>DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
А>>>>Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
А>>>>Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)

G>>>Про контекст пользователя. На сервере есть ресурсы, которые пользователь может удаленно захватывать. Ресурсы предоставляет компонент в EXE, который создан как DECLARE_CLASSFACTORY_SINGLETON. Когда пользователь отваливается, он не успевает освободить ресурс и ресурс становится недоступен другим пользователям. Мне приходит в голову только способ при помощи Ping'ов, если типа ping от пользователя не пришел, то его ресурсы можно освобождать. Или может у DCOM есть что-то типа CAsyncSocket::OnClose().


G>>>Клиент словит падения прокси при вызове методов последнего, это я понимаю, а вот как мне вычистить ссылки на серверные интерфейсы или их можно просто обнулить и как поступить со сток интерфейсами. И клиент и сервер у меня С++ интерфейсы на базе IUnknown.


А>>Про контекст пользователя: Что значит захватывать? Если на все время клиентской сессии, то лучше деражть все ресурсы в несинглтоновском серверном объекте. Тогда это объект умрет, кода умрет его единственная (если не давать его кому-то еще) прокся. Как при корректном ее релизе клиентом, так и, в идеале, при обрыве соединения или некорректной смерти клиента.

А>>Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона

А>>Ненадо ничего специально вычищать — освободи все ссылки, как при нормальном выходе и забутьте о них — заново CoCreateInstance, подписки и т.д.


G>Ресурсами выступают поворотные устройства для камер, которые висят на RS232 до 16 штук на одном порту. Все устройства адресуемые, пока пользователь крутит устройством для всех других пользователей устройство блокируется. Но другой пользователь может крутить другим устройством, отсылая команды все в тот же последовательный порт. Серверный ком-объект практически предоставляет интерфейс для работы с шиной управления (порт RS232) для многих пользователей, так что без DECLARE_CLASSFACTORY_SINGLETON не обойтись(последовательный порт-то у меня один и список доступных поворотников тоже один). За одну сессию пользователь может крутить несколькими поворотниками, последовательно их блокируя и разблокируя.


G>Уважаемый, что значит "Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона", поясните пожалуйста на моем примере.


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


1) Грубо (проверки, HRESULT, критикал секшены и т.д. опущены):

STDMETHODIMP СMySingletoneMain::CreateTurnDeviceForCameraByNum(long nCameraNum, ITurnDevice** ppTurnDevice)
{
if(DeviceIsAlreadyLocked(nCameraNum))
return E_FAIL;


*ppTurnDevice = NULL;
CComObject<CTurnDevice>* l_ppTurnDevice;
CComObject<CTurnDevice>::CreateInstance(&l_ppTurnDevice));
l_ppTurnDevice->QueryInterface(__uuidof(ITurnDevice), reinterpret_cast<void**>(ppTurnDevice));

(*ppTurnDevice)->InitWithNumAndLock(nCameraNum);
}
////////////////////////////////

STDMETHODIMP CTurnDevice::FinalConstruct()
{
m_pMySingletoneMain.CoCreateInstance(__uuidof(MySingletoneMain));
}

STDMETHODIMP CTurnDevice::FinalConstruct()
{
m_pMySingletoneMain->UnlockResourceByNum(m_nCameraNum);

}
////////////////////////////////

2) Конечно AtlUnadvise зафэйлится :). Просто отрелизь синк и забудь.
Проблема гинилого прокси синка на сервере — проблема имплементации кода, который файрит нитификаэшены на сервере.

3)В варианте с пингом прийдется делать нить-агента для разлочивания давнонепингуемых ресурсов — имхо сложнее, но немного надежнее.
Re[6]: Обрыв соединения в DCOM
От: Аноним  
Дата: 10.07.01 17:03
Оценка:
Здравствуйте Аноним, вы писали:

А>Здравствуйте Grenal, вы писали:


G>>Здравствуйте Аноним, вы писали:


А>>>Здравствуйте Grenal, вы писали:


G>>>>Здравствуйте Аноним, вы писали:


А>>>>>Здравствуйте Grenal, вы писали:


G>>>>>>Такая проблема — сервер падает, перегрузили его. Как клиенту словить этот факт и корректно почистить дохлые ссылки на серверные интерфейсы, а так же стоки. Аналогично для сервера, как освободить контекст пользователя, если он внезапно отвалился. Буду благодарен дюбым размышлениям на эту тему, а то я уже вторую неделю думаю, ничего не придумывается :(


А>>>>>Что такое "контекст пользователя"?

А>>>>>DCOM сам отвалит гнилые прокистабы (у DCOM'а есть пинг)
А>>>>>Клиент "словит" факт падения сервера при попытки вызвать метод гнилового прокси.
А>>>>>Если нужно знать это в рантайме — напиши свой метод Ping у какого-нибудь объекта и дергай его каждые n секунд (QueryInterface или AddRef в этой роли не годятся, т.к. DCOM кэширует эти вызовы)

G>>>>Про контекст пользователя. На сервере есть ресурсы, которые пользователь может удаленно захватывать. Ресурсы предоставляет компонент в EXE, который создан как DECLARE_CLASSFACTORY_SINGLETON. Когда пользователь отваливается, он не успевает освободить ресурс и ресурс становится недоступен другим пользователям. Мне приходит в голову только способ при помощи Ping'ов, если типа ping от пользователя не пришел, то его ресурсы можно освобождать. Или может у DCOM есть что-то типа CAsyncSocket::OnClose().


G>>>>Клиент словит падения прокси при вызове методов последнего, это я понимаю, а вот как мне вычистить ссылки на серверные интерфейсы или их можно просто обнулить и как поступить со сток интерфейсами. И клиент и сервер у меня С++ интерфейсы на базе IUnknown.


А>>>Про контекст пользователя: Что значит захватывать? Если на все время клиентской сессии, то лучше деражть все ресурсы в несинглтоновском серверном объекте. Тогда это объект умрет, кода умрет его единственная (если не давать его кому-то еще) прокся. Как при корректном ее релизе клиентом, так и, в идеале, при обрыве соединения или некорректной смерти клиента.

А>>>Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона

А>>>Ненадо ничего специально вычищать — освободи все ссылки, как при нормальном выходе и забутьте о них — заново CoCreateInstance, подписки и т.д.


G>>Ресурсами выступают поворотные устройства для камер, которые висят на RS232 до 16 штук на одном порту. Все устройства адресуемые, пока пользователь крутит устройством для всех других пользователей устройство блокируется. Но другой пользователь может крутить другим устройством, отсылая команды все в тот же последовательный порт. Серверный ком-объект практически предоставляет интерфейс для работы с шиной управления (порт RS232) для многих пользователей, так что без DECLARE_CLASSFACTORY_SINGLETON не обойтись(последовательный порт-то у меня один и список доступных поворотников тоже один). За одну сессию пользователь может крутить несколькими поворотниками, последовательно их блокируя и разблокируя.


G>>Уважаемый, что значит "Создать такой объект можно и вызовом какого-нибудь метода вашего синглтона", поясните пожалуйста на моем примере.


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


А>1) Грубо (проверки, HRESULT, критикал секшены и т.д. опущены):


А>STDMETHODIMP СMySingletoneMain::CreateTurnDeviceForCameraByNum(long nCameraNum, ITurnDevice** ppTurnDevice)

А>{
А> if(DeviceIsAlreadyLocked(nCameraNum))
А> return E_FAIL;


А>*ppTurnDevice = NULL;

А>CComObject<CTurnDevice>* l_ppTurnDevice;
А>CComObject<CTurnDevice>::CreateInstance(&l_ppTurnDevice));
l_ppTurnDevice->>QueryInterface(__uuidof(ITurnDevice), reinterpret_cast<void**>(ppTurnDevice));

(*ppTurnDevice)->>InitWithNumAndLock(nCameraNum);
А>}
А>////////////////////////////////

А>STDMETHODIMP CTurnDevice::FinalConstruct()

А>{
А>m_pMySingletoneMain.CoCreateInstance(__uuidof(MySingletoneMain));
А>}

А>STDMETHODIMP CTurnDevice::FinalConstruct()

А>{
m_pMySingletoneMain->>UnlockResourceByNum(m_nCameraNum);

А>}

А>////////////////////////////////

А>2) Конечно AtlUnadvise зафэйлится :). Просто отрелизь синк и забудь.

А>Проблема гинилого прокси синка на сервере — проблема имплементации кода, который файрит нитификаэшены на сервере.

А>3)В варианте с пингом прийдется делать нить-агента для разлочивания давнонепингуемых ресурсов — имхо сложнее, но немного надежнее.



Сорри, FinalRelease последний метод, конечно... :)
Re[7]: Обрыв соединения в DCOM
От: Grenal  
Дата: 11.07.01 04:33
Оценка:
А>>1) Грубо (проверки, HRESULT, критикал секшены и т.д. опущены):

А>>STDMETHODIMP СMySingletoneMain::CreateTurnDeviceForCameraByNum(long nCameraNum, ITurnDevice** ppTurnDevice)

А>>{
А>> if(DeviceIsAlreadyLocked(nCameraNum))
А>> return E_FAIL;


А>>*ppTurnDevice = NULL;

А>>CComObject<CTurnDevice>* l_ppTurnDevice;
А>>CComObject<CTurnDevice>::CreateInstance(&l_ppTurnDevice));
l_ppTurnDevice->>>QueryInterface(__uuidof(ITurnDevice), reinterpret_cast<void**>(ppTurnDevice));

(*ppTurnDevice)->>>InitWithNumAndLock(nCameraNum);
А>>}
А>>////////////////////////////////

А>>STDMETHODIMP CTurnDevice::FinalConstruct()

А>>{
А>>m_pMySingletoneMain.CoCreateInstance(__uuidof(MySingletoneMain));
А>>}

А>>STDMETHODIMP CTurnDevice::FinalConstruct()

А>>{
m_pMySingletoneMain->>>UnlockResourceByNum(m_nCameraNum);

А>>}

А>>////////////////////////////////

А>>2) Конечно AtlUnadvise зафэйлится :). Просто отрелизь синк и забудь.

А>>Проблема гинилого прокси синка на сервере — проблема имплементации кода, который файрит нитификаэшены на сервере.

А>>3)В варианте с пингом прийдется делать нить-агента для разлочивания давнонепингуемых ресурсов — имхо сложнее, но немного надежнее.



А>Сорри, FinalRelease последний метод, конечно... :)


Понял! Больщое спасибо, буду пробовать.
А с AtlUnadvise, была моя ошибка — после падения клиента я не мог разместить кук GTI в std::map на сервере, а клиенту возвращал CONNECT_E_ADVISELIMIT. Теперь поправлено.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.