Re: Работа в сети | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Лишняя блокировка это плохо. Это кувалдой стучать по заедающему замку, вместо того чтобы смазать его
Предварительный шаг теста. Можно и на одной машине проверять, можно и на разных, сделав SET DEFAULT TO \\общая_шара
Одна копия фокса - "писатель"
Другая копия фокса (на другой машине для полноты эксперимента) - "читатель"
Если в "читателе" не настроить SET REFRESH (оставить по умолчанию - 5 секунд) и не применять SYS(1104), то будет видно что "свежее" значение считывается лишь раз в 5 секунд. ------------------ WBR, Igor |
Re: Работа в сети | |
---|---|
of63 Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
> GO RECNO() && это нужно всегда
у меня такого нет, и не может быть. Есть SELECT FROM... И еще. Что дает GO ? Перемещение к нужной записи (и ее перечтение)? А если записи "соседние" физически, и находятся в одном блоке в кеше ОС? |
Re: Работа в сети | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Для SELECT ... FROM есть свои нюансы - именно про то и была тема в FIDO - иногда автооткрываемая им таблица и последующее чтение из неё (а SELECT по сути такие же чтения делает как и простое alias.field в цикле - разницы в части метода обращения к данным в записях таблицы нет) таки показывали "старые" данные - при том даже не 5-секундной давности, а многочасовой. Если в другой датасессии давным давно была открыта эта же таблица, и там она висит "без движения". Фокс же общий кэш держит на все курсоры из ряда USE ... AGAIN или просто открытия в разных датасессиях.
GO RECNO() как раз и даёт "перечитывание записи" - но не совсем "из файла" - из кэша фокса. Потому одного его и недостаточно для чтения изменяющихся из другой программы данных. Ключевой момент тут в том, что ? c1 просто НИКОГДА не вернёт "свежие" данные сам по себе. Надо вынудить фокс перечитать запись - GO RECNO() самый простой вариант. Можно и какой Refresh "привязанного" текстбокса/грида использовать к примеру... Да без разницы это. Тут играет значение кэш фокса, а не кэш читаемых ОС файлов. А фокс таки на уровне отдельных записей работает, а не страниц/кластеров/секторов Файловой системы. Конечно же он мультиплексирует обращения к физическому файлу, т.е. при "массовом" чтении начинает запрашивать записи не по одной, а большими блоками - но тут не про это разговор... Важно что до истечения интервала SET REFRESH фокс не будет свой кэш обновлять - и то что там было так и будет возвращаться в "старом" виде. Конечно же "вновь считанные" записи будут уже со "свежими данными". Это несложно увидеть, если делать тот же SELECT запрос (без упорядочения), на фоне процесса-писателя, обновляющего записи в "обратном" порядке. Ещё веселее будет с "оптимизированным" запросом. Думаю что вполне можно "поймать" такую ситуацию, когда на момент чтения индекса из cdx (в процессе "оптимального" исполнения запроса с условием) запись "подходила", а как дошло до собственно чтения записи из dbf, она уже изменилась. Фокс ведь не обеспечивает "согласованного чтения" - да и вообще "уровни изоляции транзакций" у него, мягко говоря, слабовато реализованы. ------------------ WBR, Igor |
Re: Работа в сети | |
---|---|
of63 Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
Ладно, спс за на водку ) Если попробую, напишу результат. Как всегда половина непонятна:
- датасессий нет, автооткрытий таблиц нет (открыты все время, что может и к худшему) - SELECT по сути такие же чтения делает как и простое alias.field в цикле - а как он делает простое alias.field ? Просто FSEEK() и FREAD() (на API-шном уровне) ? Тогда виновата ОС. Или есть фоксовая прослойка, тогда виноват фокс, или ОС... - вынудить фокс перечитать запись - GO RECNO() самый простой вариант - куда его удвигать, если я собираюсь прочитать несколько записей из разных частей файла таблицы? |
Re: Работа в сети | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Насколько я помню, с USE ... AGAIN ситуация такая же как и с разными датасессиями. А фокс вполне себе может для целей выполнения запроса провернуть аналог USE ... AGAIN Уверен что гораздо сложнее чем тривиальное чтение пары байт из файла. Там масса самых разных "прослоек" и кэшей, с которыми требуется производить определённые манипуляции. "Вычислитель выражений", очевидно, в отдельную область памяти копирует данные из соответствующего куска памяти где фокс держит кэш таблицы (а может быть ещё отдельно и всю запись копирует из этого кэша "куда поближе" прежде чем выделить в ней кусок отвечающий за соответствующее поле). Плюс нехилая логика управления кэшем, которая и определяет когда FREAD делать, а когда можно забить и старые байтики из кэша забирать. Это даже не приближаясь к собственно "буферизации" - когда помимо кэша с "физическими" записями фокс ещё и этот самый буфер держит - где будут и "текущие несохранённые" данные, плюс "старые, на момент начала редактирования"... Нет, ну если ты и так будешь перемещать указатель записей, то GO RECNO() не нужен - он как раз для случая когда сидим на одной и той же записи (как в примере, и как, наверняка, было у автора вопроса), но хотим её "свежее значение" получить. Почему ему и помогло (частично) "открытие в BROWSE" - для грида/бровза и даже простого одиночного текстбокса фокс отслеживает "надобность в перерисовке" - и делает то же самое что и .refresh() при некоторых "манипуляциях" с таким объектом - скажем потеря/получение фокуса... Правильнее, конечно, было бы сказать что .refresh() это принудительный вызов этой самой логики "вычитывания данных из поля/записи" и помещения его в ещё один буфер - отображаемое и редактируемое в контроле значение Да, если не рассматривать всё по отдельности, то от нагромождения этих самых "буферов" запросто крыша поехать может ------------------ WBR, Igor |
Re: Работа в сети | |
---|---|
of63 Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
Почему ты упоминаешь .Refresh() ? В твоем примере нет ни одного обьекта (Грида, формы), никакие поля не привязаны к курсору. Чисто SELECT FROM или ? таблица.поле...
Как устроены кэши фокса - хз, вряд ли разрабы лишних кешей понасоздавали, в ДОСе лишнего не использовали. Да и знать мне не надо про ихнее количество перекеширований, мне надо заставить фокс заставить ОС слазить на файл-сервер ) Карту-схему своих кешей разрабы не оставили... Откуда ты все знаешь? Да я и сам пишу так, что потом у меня же крыша едет. А все потому, что простую идею применяешь к все более и более общим и малоподходящим случаям, непредусмотренным заранее, и простые пара строчек обернуты в 1000 строк ИФ-ов |
Re: Работа в сети | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Потому что ситуации разные бывают И надо понимать что, к примеру, долбя в цикле ? c1 мы будем до скончания века наблюдать одну и ту же "печальную картину" безнадёжно устаревших данных, а отобразив это же поле test.c1 в текстбоксе, и банально "потопча" его мышкой, мы чудесным образом будем получать периодически свежее значение.
Насчёт лишнего - это ты думаешь что оно "лишнее" - применимо к конкретному способу использования (UseCase), а разрабы то прекрасно понимают что совсем даже и не лишнее, а жизненно необходимое. Чтобы не получать производительность на уровне "в час по чайной ложке", а чтобы оно "летало" - ну насколько это возможно Я не "знаю", я предполагаю и наблюдаю - от совсем уж внешних проявлений - например FileMon показывает какие "куски" каких файлов процесс считывает/записывает/блокирует/разблокирует, до более глубокого взгляда на память фокса из Win32 отладчика... Исходников у меня нет, и реверсингом я не занимаюсь (тем более такого гигантского по объёму кода продукта как фокс, даже чисто его рантайм) так что "точно знать" я никак не могу. ------------------ WBR, Igor |
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 |
Re: Работа в сети | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Во-первых фокс таки "позаписно" пишет, а не "по одному полю". Во-вторых "другие" узнают про это лишь тогда когда заново считают эту запись. А когда именно это произойдёт - и зависит от настройки SET REFRESH (она по сути ограничивает частоту повторных чтений - т.е. говорит "прочёл - теперь не раньше чем через 5 секунд снова ту же запись можешь читать"), функции SYS(1104) (она говорит - наплевать на все ограничения - читай, мил человек, свежачок) и собственно кода чтения - просто обращения к alias.field не достаточно для "повторного чтения". Перемещение указателя записи, рефреш связанного визуального контрола, те же LOCK/UNLOCK, попытка изменения поля (там неявный LOCK, а может и UNLOCK сработает, если не включена оптимистическая буферизация) - эти события приведут к тому что фокс заново считает запись. Во многих ОС и ФС как раз кое что есть. В винде, к примеру, есть directory change notification - но не для байтиков внутри файла, а для уровня собственно файлов/папок. Одно из отслеживаемых событий это "изменение времени последней записи в файл" - правда точность этого механизма недостаточна для практического использования в СУБД (хотя в некоторых программах это активно используют - та же VisualStudio замечательно "видит" если открытый в ней файл был изменён "снаружи", и предлагает его "освежить" - т.е. считать заново)... Фокс, естественно, на это не рассчитан - не в те годы он создавался... Они (блокировки) не для того предназначены... Это способ избежать безобразной "одновременной" записи в одно и то же место разных данных. Чтобы половина буковок (или даже бит) записалась из одного источника, а вторая половина из другого. Таймер то зачем? Для самой системы таймер не нужен. Ты же пишешь программу и в какой-то момент её исполнения фокс видит - ага, запросили поле - вот тогда он и будет его читать, НО для повышения скорости работы таки проверит, "а не читал ли я этот файл всего 1 секунду назад" - и если читал, и при том нужная запись есть в кэше - он "оптимизирует" работу, не обращаясь к файлу на диске (потенциально сетевом), а напрямую взяв данные из кэша... "Предсказатель" тоже имеется - не в курсе как и что он "предсказывает", но при "многозаписных" и неоптимизированных (ну когда выборка "всей таблицы" идёт) select-sql запросах видно что чтение последовательных записей из dbf файла идёт "по нарастающей" - сначала одну, потом следующие две, потом уже четыре, и так до достижения определённого "размера блока" - не помню, вроде он не больше 64Кб в размере... Там уже особого проку от замены двух чтений на одно, вероятно, не будет. Работает ли эта мулька для "тривиальных SCAN-ов" я как-то не проверял (запросы были много любопытнее "антикварного подхода"), но думаю что тоже вполне себе может... Раз уж FOR они там могут оптимизировать "по индексу", то отчего бы и просто "чтение подряд" не оптимизировать, мультиплексируя запросы отдельных записей... P.S. Кстати, некоторого рода таймер для "перечитывания данных без команд" всё же есть - управляется 1 параметром SET REFRESH (по умолчанию он отключен - т.е. стоит интервал обновления 0) и работает для записей отображаемых в BROWSE-окне. Т.е. там они могут "сами по себе" обновляться - даже без тыкания мышкой/листания этого окошка. ------------------ WBR, Igor Исправлено 1 раз(а). Последнее : Igor Korolyov, 19.01.18 00:34 |
Re: Работа в сети | |
---|---|
of63 Сообщений: 25254 Откуда: Н.Новгород Дата регистрации: 13.02.2008 |
Вот, кратко ты не умеешь говорить ). Идея (маленькое предположение) понятна - пока сам не попробуешь, тогда всем и расскажешь красиво, если эксперимент удастся в пользу экспериментатора )))
|
© 2000-2024 Fox Club  |