Форум » LetoDB, HbNetio. » Leto DB Server (продолжение 9) » Ответить

Leto DB Server (продолжение 9)

Dima: Продолжаем тут

Ответов - 301, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 All

Pasha: Согласен. А в исходниках сервера можно убрать ветки для xHarbour. Только ветки с __OLDRDD__ я еще использую (для xHarbour)

alkresin: Что-то до меня никак не доходит смысл конструкции в leto_ConnectionClose(): pConnection->bCloseAll = 0; hb_rddIterateWorkAreas( leto_CheckAreas, (void *) pConnection ); if( pConnection->bCloseAll ) leto_CloseAll( pConnection ); leto_CheckAreas() проверяет, принадлежит ли area этому соединению и является ли она leto area. Если хоть одна такая area находится, то тогда выполняется leto_closeall() - а там опять такая же проверка ( в leto_doclose() ). Почему нельзя сразу вызвать leto_closeall() ? И непонятно, зачем в leto_closeall() перед и после вызова hb_rddIterateWorkAreas() устанавливается pConnection->bCloseAll ?

Pasha: leto_ConnectionClose() вызывается по leto_disconnect(), или при завершении программы. Должно быть закрыто только указанное соединение, или текущее. При вызове leto_disconnect() могут быть открыты рабочие области на нескольких серверах letodb, и локальные р.о. По hb_rddIterateWorkAreas проверяется, открыта ли хотя бы одна р.о. на этом сервере. Если открыта - тогда надо выдать команду этому серверу, и только этому: close_all. Если нет открытых р.о. - то такую команду именно этому серверу выдавать незачем. Все остальные р.о. - с других серверов letodb и локальные - должны остаться открытыми.


alkresin: Pasha пишет: Если открыта - тогда надо выдать команду этому серверу, и только этому: close_all Но ведь такая же проверка осуществляется еще раз в leto_doClose(). Т.е. можно в leto_doClose() добавить строчку: if( leto_CheckAreaConn( pArea, ( LETOCONNECTION * ) p ) ) { SELF_CLOSE( pArea ); pConnection->bCloseAll = 1; } и в leto_CloseAll() выдавать команду close_all, если установлен pConnection->bCloseAll: if( pConnection->bCloseAll ) Тогда мы избавляемся от того лишнего кода в leto_ConnectionClose() и от функции leto_CheckAreas(), которая только оттуда вызывается. Или я что-то упустил ?

Pasha: leto_closeAll безусловно выдает команду серверу "close_all". А если уже все р/о с этого сервера закрыты, то эта команда не нужна. Вот и делается дополнительная проверка перед вызовом leto_closeAll(), нужен ли вообще этот вызов. Хотя конечно, можно объединить все в hb_rddIterateWorkAreas. Но тогда в pConnection надо добавить еще один флаг, дополнительно к bCloseAll

alkresin: Зачем еще один флаг ? static ERRCODE leto_doClose( AREAP pArea, void * p ) { if( leto_CheckAreaConn( pArea, ( LETOCONNECTION * ) p ) ) { SELF_CLOSE( pArea ); pConnection->bCloseAll = 1; } return SUCCESS; } BOOL leto_CloseAll( LETOCONNECTION * pConnection ) { char szData[16]; hb_rddIterateWorkAreas( leto_doClose, (void *) pConnection ); if( pConnection->bCloseAll ) { if( leto_CheckServerVer( pConnection, 100 ) ) sprintf( szData,"close_all;\r\n" ); else sprintf( szData,"close;00;\r\n" ); pConnection->bCloseAll = 0; if( leto_DataSendRecv( pConnection, szData, 0 ) ) return TRUE; else return FALSE; } else return TRUE; } void leto_ConnectionClose( LETOCONNECTION * pConnection ) { if( pConnection->pAddr ) { leto_CloseAll( pConnection ); ... } }

Pasha: Так в SELF_CLOSE( pArea ) используется флаг bCloseAll, чтобы не выдавать серверу команды close. А тут он используется еще и для того, чтобы отметить, есть ли открытые р/о с этого сервера. Вот поэтому и нужны 2 флага: один для SELF_CLOSE, а второй - чтобы затем определить, выдавать или нет команду close_all.

alkresin: Так в SELF_CLOSE( pArea ) используется флаг bCloseAll, чтобы не выдавать серверу команды close. Ну так поменяем местами строчки в предлагаемом варианте leto_doClose() и этот флаг выполнит обе функции: static ERRCODE leto_doClose( AREAP pArea, void * p ) { if( leto_CheckAreaConn( pArea, ( LETOCONNECTION * ) p ) ) { pConnection->bCloseAll = 1; SELF_CLOSE( pArea ); } return SUCCESS; }

Pasha: Да, так сработает.

Pasha: Хотя нет. Вызов то будет для всех р.о, в том числе с других серверов. Тогда будут закрыты р.о., которые закрывать не надо.

alkresin: Хотя нет. Вызов то будет для всех р.о, в том числе с других серверов Какой вызов ? Сигнал close_all ? Так он посылается по одному определенному соединению, на один сервер.

Pasha: Это я уже туплю. Все там в порядке.

alkresin: Ok. Я сейчас в этом копаюсь, потому что хочу разбить клиентский модуль на две части, выделить client engine, который не будет содержать вызовов Harbour функций и может использоваться в приложениях на других языках. К тому же это позволит упростить и лучше структуировать код.

Pasha: Хорошее дело, и нужное, только сложное. А какие есть планы по клиентской библиотеке ? Просто сделать dll по типу ace32 ?

alkresin: Хорошее дело, и нужное, только сложное. Буду делать постепенно - сначала connect/disconnect, management функции, запись/чтение переменных - уже в таком наборе это можно использовать. Потом одну за другой функции для работы с БД. А какие есть планы по клиентской библиотеке ? Просто сделать dll по типу ace32 ? Есть 3 C файла - letoclient.c, common_c.c, blowfish.c, их можно непосредственно включить в проект, или построить из них dll или lib. А какие еще варианты ?

alkresin: Объясните мне, пожалуйста, еще такую вещь: leto_GetServerCdp() вызывается только из leto_ConnectionNew(), т.е. когда pConnection только создан и pConnection->pCdpTable пуста - и leto_GetServerCdp() ничего там найти не может ...

Pasha: Я уже с трудом вспоминаю тот алгоритм. Кажется, предусматривалось вот что: Сначала надо установить текущее соединение через вызов RDDI_CONNECTION. Затем задать таблицу соответствия кодовых страниц вызовами LETO_ADDCDPTRANSLATE И только после этого коннектиться к серверу.

alkresin: RDDI_CONNECTION закомментарен. Но, в любом случае, это не может работать, поскольку leto_GetServerCdp() вызывается только из leto_ConnectionNew(), т.е. до того как LETO_ADDCDPTRANSLATE могла бы отработать.

Pasha: В функции leto_writelog может быть стоит оставить одну ветку, с вызовами hb_fs* ? Эта ветка выполняет все необходимые функции. Зачем тянуть лишнюю ссылку на hb_fopen ?

Pasha: alkresin пишет: RDDI_CONNECTION закомментарен. Но, в любом случае, это не может работать, поскольку leto_GetServerCdp() вызывается только из leto_ConnectionNew(), т.е. до того как LETO_ADDCDPTRANSLATE могла бы отработать. Да нет там комментария: case RDDI_CONNECTION: ... А структура letoConnPool выделяется в letoInit, т.е до вызова leto_ConnectionNew(). По RDDI_CONNECTION можно установить текущее соединение, тоже до первого коннекта. И LETO_ADDCDPTRANSLATE сможет отработать.



полная версия страницы