:: Visual Foxpro, Foxpro for DOS
Re: Работа в сети
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Лишняя блокировка это плохо. Это кувалдой стучать по заедающему замку, вместо того чтобы смазать его
Предварительный шаг теста. Можно и на одной машине проверять, можно и на разных, сделав SET DEFAULT TO \\общая_шара
CREATE TABLE test (c1 c(50))
APPEND BLANK
USE

Одна копия фокса - "писатель"
USE test
SET REPROCESS TO 1
DO WHILE INKEY(0.5)<> 32
REPLACE c1 WITH TRANSFORM(SECONDS())
ENDDO

Другая копия фокса (на другой машине для полноты эксперимента) - "читатель"
USE test
CLEAR
*SET REFRESH TO 0, -1 && если это раскомментировать, можно убрать SYS(1104)
DO WHILE INKEY(0.5)<>32
GO RECNO() && это нужно всегда
SYS(1104) && вместо SET REFRESH
? c1
ENDDO

Если в "читателе" не настроить SET REFRESH (оставить по умолчанию - 5 секунд) и не применять SYS(1104), то будет видно что "свежее" значение считывается лишь раз в 5 секунд.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Работа в сети
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> GO RECNO() && это нужно всегда
у меня такого нет, и не может быть. Есть SELECT FROM...
И еще. Что дает GO ? Перемещение к нужной записи (и ее перечтение)? А если записи "соседние" физически, и находятся в одном блоке в кеше ОС?
Ratings: 0 negative/0 positive
Re: Работа в сети
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Для SELECT ... FROM есть свои нюансы - именно про то и была тема в FIDO - иногда автооткрываемая им таблица и последующее чтение из неё (а SELECT по сути такие же чтения делает как и простое alias.field в цикле - разницы в части метода обращения к данным в записях таблицы нет) таки показывали "старые" данные - при том даже не 5-секундной давности, а многочасовой. Если в другой датасессии давным давно была открыта эта же таблица, и там она висит "без движения". Фокс же общий кэш держит на все курсоры из ряда USE ... AGAIN или просто открытия в разных датасессиях.
GO RECNO() как раз и даёт "перечитывание записи" - но не совсем "из файла" - из кэша фокса. Потому одного его и недостаточно для чтения изменяющихся из другой программы данных. Ключевой момент тут в том, что ? c1 просто НИКОГДА не вернёт "свежие" данные сам по себе. Надо вынудить фокс перечитать запись - GO RECNO() самый простой вариант. Можно и какой Refresh "привязанного" текстбокса/грида использовать к примеру...
of63
А если записи "соседние" физически, и находятся в одном блоке в кеше ОС?
Да без разницы это. Тут играет значение кэш фокса, а не кэш читаемых ОС файлов. А фокс таки на уровне отдельных записей работает, а не страниц/кластеров/секторов Файловой системы. Конечно же он мультиплексирует обращения к физическому файлу, т.е. при "массовом" чтении начинает запрашивать записи не по одной, а большими блоками - но тут не про это разговор... Важно что до истечения интервала SET REFRESH фокс не будет свой кэш обновлять - и то что там было так и будет возвращаться в "старом" виде. Конечно же "вновь считанные" записи будут уже со "свежими данными". Это несложно увидеть, если делать тот же SELECT запрос (без упорядочения), на фоне процесса-писателя, обновляющего записи в "обратном" порядке. Ещё веселее будет с "оптимизированным" запросом. Думаю что вполне можно "поймать" такую ситуацию, когда на момент чтения индекса из cdx (в процессе "оптимального" исполнения запроса с условием) запись "подходила", а как дошло до собственно чтения записи из dbf, она уже изменилась. Фокс ведь не обеспечивает "согласованного чтения" - да и вообще "уровни изоляции транзакций" у него, мягко говоря, слабовато реализованы.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Работа в сети
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ладно, спс за на водку ) Если попробую, напишу результат. Как всегда половина непонятна:
- датасессий нет, автооткрытий таблиц нет (открыты все время, что может и к худшему)
- SELECT по сути такие же чтения делает как и простое alias.field в цикле - а как он делает простое alias.field ? Просто FSEEK() и FREAD() (на API-шном уровне) ? Тогда виновата ОС. Или есть фоксовая прослойка, тогда виноват фокс, или ОС...
- вынудить фокс перечитать запись - GO RECNO() самый простой вариант - куда его удвигать, если я собираюсь прочитать несколько записей из разных частей файла таблицы?
Ratings: 0 negative/0 positive
Re: Работа в сети
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
- датасессий нет, автооткрытий таблиц нет (открыты все время, что может и к худшему)
Насколько я помню, с USE ... AGAIN ситуация такая же как и с разными датасессиями. А фокс вполне себе может для целей выполнения запроса провернуть аналог USE ... AGAIN
of63
а как он делает простое alias.field ? Просто FSEEK() и FREAD() (на API-шном уровне) ? Тогда виновата ОС. Или есть фоксовая прослойка, тогда виноват фокс, или ОС...
Уверен что гораздо сложнее чем тривиальное чтение пары байт из файла. Там масса самых разных "прослоек" и кэшей, с которыми требуется производить определённые манипуляции. "Вычислитель выражений", очевидно, в отдельную область памяти копирует данные из соответствующего куска памяти где фокс держит кэш таблицы (а может быть ещё отдельно и всю запись копирует из этого кэша "куда поближе" прежде чем выделить в ней кусок отвечающий за соответствующее поле). Плюс нехилая логика управления кэшем, которая и определяет когда FREAD делать, а когда можно забить и старые байтики из кэша забирать.
Это даже не приближаясь к собственно "буферизации" - когда помимо кэша с "физическими" записями фокс ещё и этот самый буфер держит - где будут и "текущие несохранённые" данные, плюс "старые, на момент начала редактирования"...
of63
- куда его удвигать, если я собираюсь прочитать несколько записей из разных частей файла таблицы?
Нет, ну если ты и так будешь перемещать указатель записей, то GO RECNO() не нужен - он как раз для случая когда сидим на одной и той же записи (как в примере, и как, наверняка, было у автора вопроса), но хотим её "свежее значение" получить. Почему ему и помогло (частично) "открытие в BROWSE" - для грида/бровза и даже простого одиночного текстбокса фокс отслеживает "надобность в перерисовке" - и делает то же самое что и .refresh() при некоторых "манипуляциях" с таким объектом - скажем потеря/получение фокуса... Правильнее, конечно, было бы сказать что .refresh() это принудительный вызов этой самой логики "вычитывания данных из поля/записи" и помещения его в ещё один буфер - отображаемое и редактируемое в контроле значение

Да, если не рассматривать всё по отдельности, то от нагромождения этих самых "буферов" запросто крыша поехать может


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Работа в сети
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Почему ты упоминаешь .Refresh() ? В твоем примере нет ни одного обьекта (Грида, формы), никакие поля не привязаны к курсору. Чисто SELECT FROM или ? таблица.поле...

Как устроены кэши фокса - хз, вряд ли разрабы лишних кешей понасоздавали, в ДОСе лишнего не использовали. Да и знать мне не надо про ихнее количество перекеширований, мне надо заставить фокс заставить ОС слазить на файл-сервер ) Карту-схему своих кешей разрабы не оставили... Откуда ты все знаешь?

Да я и сам пишу так, что потом у меня же крыша едет. А все потому, что простую идею применяешь к все более и более общим и малоподходящим случаям, непредусмотренным заранее, и простые пара строчек обернуты в 1000 строк ИФ-ов
Ratings: 0 negative/0 positive
Re: Работа в сети
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Потому что ситуации разные бывают И надо понимать что, к примеру, долбя в цикле ? c1 мы будем до скончания века наблюдать одну и ту же "печальную картину" безнадёжно устаревших данных, а отобразив это же поле test.c1 в текстбоксе, и банально "потопча" его мышкой, мы чудесным образом будем получать периодически свежее значение.
Насчёт лишнего - это ты думаешь что оно "лишнее" - применимо к конкретному способу использования (UseCase), а разрабы то прекрасно понимают что совсем даже и не лишнее, а жизненно необходимое. Чтобы не получать производительность на уровне "в час по чайной ложке", а чтобы оно "летало" - ну насколько это возможно
Я не "знаю", я предполагаю и наблюдаю - от совсем уж внешних проявлений - например FileMon показывает какие "куски" каких файлов процесс считывает/записывает/блокирует/разблокирует, до более глубокого взгляда на память фокса из Win32 отладчика... Исходников у меня нет, и реверсингом я не занимаюсь (тем более такого гигантского по объёму кода продукта как фокс, даже чисто его рантайм) так что "точно знать" я никак не могу.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Работа в сети
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Ну... я "вообще" не могу представить, как работают фоксы с сетевой табличкой на файл-сервере (далее ФС). Вот один юзер меняет в ней 1 байт (поле переписал). Когда/как все юзеры этой же таблички узнАют об этом событии? Сигналы изменяющий юзер не рассылает (и механизма то такого нет в ФС парадигме). Читал про блокировку - эта штука сама по себе сетевая (факт блокирования должен обслуживать САМ ФС, и обслуживает! иначе бы ничего сетевого в фоксе не работало), но она вроде не годится для этого оповещения (события блокировки же не поступают ко всем юзерам). Тогда остается просто ИИ фокса + опрос по таймеру, или по необходимости (?), есть единственная команда для этого дела - SET REFRESH. Про команду GO для этой цели - вроде тоже не хорошо, при каждом смещении RECNO() лезть на сервер, значит в фоксе надо иметь предсказатель следующих RECNO(), чтобы читать пачками...

Экспериментировать надо вобщем, а как всегда, времени нет, ...пока ракеты не начнут падать чаще, то и не будет )

Доб. На всякий, имя ф-ии блокировки:
BOOL LockFile(
HANDLE hFile, // дескриптор файла
DWORD dwFileOffsetLow, // младшее слово смещения начала отрезка
DWORD dwFileOffsetHigh, // старшее слово смещения начала отрезка
DWORD nNumberOfBytesToLockLow, // младшее слово длины отрезка
DWORD nNumberOfBytesToLockHigh // старшее слово длины отрезка
);



Исправлено 1 раз(а). Последнее : of63, 18.01.18 18:17
Ratings: 0 negative/0 positive
Re: Работа в сети
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Ну... я "вообще" не могу представить, как работают фоксы с сетевой табличкой на файл-сервере (далее ФС). Вот один юзер меняет в ней 1 байт (поле переписал). Когда/как все юзеры этой же таблички узнАют об этом событии?
Во-первых фокс таки "позаписно" пишет, а не "по одному полю".
Во-вторых "другие" узнают про это лишь тогда когда заново считают эту запись. А когда именно это произойдёт - и зависит от настройки SET REFRESH (она по сути ограничивает частоту повторных чтений - т.е. говорит "прочёл - теперь не раньше чем через 5 секунд снова ту же запись можешь читать"), функции SYS(1104) (она говорит - наплевать на все ограничения - читай, мил человек, свежачок) и собственно кода чтения - просто обращения к alias.field не достаточно для "повторного чтения". Перемещение указателя записи, рефреш связанного визуального контрола, те же LOCK/UNLOCK, попытка изменения поля (там неявный LOCK, а может и UNLOCK сработает, если не включена оптимистическая буферизация) - эти события приведут к тому что фокс заново считает запись.
of63
Сигналы изменяющий юзер не рассылает (и механизма то такого нет в ФС парадигме).
Во многих ОС и ФС как раз кое что есть. В винде, к примеру, есть directory change notification - но не для байтиков внутри файла, а для уровня собственно файлов/папок. Одно из отслеживаемых событий это "изменение времени последней записи в файл" - правда точность этого механизма недостаточна для практического использования в СУБД (хотя в некоторых программах это активно используют - та же VisualStudio замечательно "видит" если открытый в ней файл был изменён "снаружи", и предлагает его "освежить" - т.е. считать заново)... Фокс, естественно, на это не рассчитан - не в те годы он создавался...
of63
Читал про блокировку - эта штука сама по себе сетевая (факт блокирования должен обслуживать САМ ФС, и обслуживает! иначе бы ничего сетевого в фоксе не работало), но она вроде не годится для этого оповещения (события блокировки же не поступают ко всем юзерам).
Они (блокировки) не для того предназначены... Это способ избежать безобразной "одновременной" записи в одно и то же место разных данных. Чтобы половина буковок (или даже бит) записалась из одного источника, а вторая половина из другого.
of63
Тогда остается просто ИИ фокса + опрос по таймеру, или по необходимости (?), есть единственная команда для этого дела - SET REFRESH. Про команду GO для этой цели - вроде тоже не хорошо, при каждом смещении RECNO() лезть на сервер, значит в фоксе надо иметь предсказатель следующих RECNO(), чтобы читать пачками...
Таймер то зачем? Для самой системы таймер не нужен. Ты же пишешь программу и в какой-то момент её исполнения фокс видит - ага, запросили поле - вот тогда он и будет его читать, НО для повышения скорости работы таки проверит, "а не читал ли я этот файл всего 1 секунду назад" - и если читал, и при том нужная запись есть в кэше - он "оптимизирует" работу, не обращаясь к файлу на диске (потенциально сетевом), а напрямую взяв данные из кэша...
"Предсказатель" тоже имеется - не в курсе как и что он "предсказывает", но при "многозаписных" и неоптимизированных (ну когда выборка "всей таблицы" идёт) select-sql запросах видно что чтение последовательных записей из dbf файла идёт "по нарастающей" - сначала одну, потом следующие две, потом уже четыре, и так до достижения определённого "размера блока" - не помню, вроде он не больше 64Кб в размере... Там уже особого проку от замены двух чтений на одно, вероятно, не будет. Работает ли эта мулька для "тривиальных SCAN-ов" я как-то не проверял (запросы были много любопытнее "антикварного подхода"), но думаю что тоже вполне себе может... Раз уж FOR они там могут оптимизировать "по индексу", то отчего бы и просто "чтение подряд" не оптимизировать, мультиплексируя запросы отдельных записей...
P.S. Кстати, некоторого рода таймер для "перечитывания данных без команд" всё же есть - управляется 1 параметром SET REFRESH (по умолчанию он отключен - т.е. стоит интервал обновления 0) и работает для записей отображаемых в BROWSE-окне. Т.е. там они могут "сами по себе" обновляться - даже без тыкания мышкой/листания этого окошка.


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 19.01.18 00:34
Ratings: 0 negative/0 positive
Re: Работа в сети
of63

Сообщений: 25254
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Вот, кратко ты не умеешь говорить ). Идея (маленькое предположение) понятна - пока сам не попробуешь, тогда всем и расскажешь красиво, если эксперимент удастся в пользу экспериментатора )))
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 15 Sejko  (Гостей: 14)

© 2000-2024 Fox Club 
Яндекс.Метрика