|
|
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Есть некот. программный автоматизированный комплекс по рассылке факсов Несколько независимых программ управления рассылкой на VB работают с одной БД MSAccess в БД есть несколько таблиц -СписокAll -общий список -Список1 -Список2 -Список3 ... -текущие списки рассылки -другие служебные таблицы... Через MSAccess для БД установлены следующие свойства Режим открытия по умолчанию -общий доступ Блокировка по умолчанию - отсутствует Блокировка записей при открытии БД -галочка не стоит Принцип работы программы управления рассылкой следующий: Из текущего списка(напр. Список 1) функцией GetZadanie (код см. ниже) считывается строчка. По завершении сеанса досылки информация заносится в 2 списка в Список1 sub WriteRezult (код см. ниже) в общий СписокAll Sub RefreshMainBaza (код см. ниже) Таких программ 5 штук. Если программа1 и программа2 работают с одним и тем же Список1, то программа1 считывает первую строчку согласно kritBD = "Выполнено = 'нет'", а программа2 считывает вторую строчку, т.е. в функции GetZadanie добавлено MoveNext, чем исключено одновременное обращение к одной и той же строчке. в одной(лишь!) -(устаревшая версия) программе использован элемент Data и DAO для отображения списка типа Список1 в самой программе. также к базе обращаются в автомате еще несколько служебных программок(но к другим таблицам), коды аналогичны приведенным ниже Суть проблемы: периодически, не так чтобы очень часто но бывает раз в несколько часов одна из программ, управляющих факсами может вылететь, при этом пишется: ERROR '-2147467259 (80004005)' База данных была приведена пользователем 'admin' на компьютере Notebook в состояние, препятствующее ее открытию и блокировке. или ERROR '-2147467259 (80004005)' База данных была приведена пользователем 'admin' на компьютере D в состояние, препятствующее ее открытию и блокировке.(P.S. Notebook -это PC, на кот.все установлено, D - это рабочий PC, находящийся в сети с Notebook, на кот. тоже есть программы, работающие с этой БД преимущественно в ручном режиме, хотя есть и маленькие служебные, работающие в автомате) Скажем так, мне не столь важно, чтобы все корректно записалось, раз уж ошибка произошла, но мне критично, чтоб программа не вылетала, а место ошибки и причину я понять не могу. Хотя и догадываюсь, что ошибка кроеся в ф-циях, подобных тем, что приведены ниже. ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Baza & ";Mode=Share Deny None;Persist Security Info=False" AdoConnection.Open ConnectionString RSBaza.CursorType = adOpenStatic RSBaza.LockType = adLockOptimistic Я в этих параметрах плохо разбираюсь, код естественно где-то срисовал. Можно было бы конечно запустить программу в режиме отладки, но: 1) ошибки ждать долго и непонятно в какой именно из программ она возникнет 2) На PC где все это стоит (Notebook) установлен WIN 2003, куда VB6 не хочет устанавливаться, в силу как это не парадоксально отсутствия в системе корректно работающей виртуальной машины DOS, поэтому на сегодняшний день все программы пишутся и компилируются на PC 'D' , там win98, а потом уже переносятся на win2003 server. P.S. примеры кодов --------------------------------------------------------- Sub RefreshMainBaza(FaxNumber As String, Logrezult As LogType5, Baza As String, Table As String) 'процедура записи данных о звонке в основную таблицу БД 'процедура обновляет статистику досылки в основной таблице БД 'для номера FaxNumber на основании данных протокола LogRezalt Dim kritBD As String 'критерий для отбора записей из основной таблицы БД Dim RezTM As Date 'время начала сеанса связи Dim AdoConnection As ADODB.Connection Dim RSBaza As ADODB.Recordset kritBD = "Факс = '" & FaxNumber & "'" Set AdoConnection = CreateObject("ADODB.Connection") Set RSBaza = CreateObject("ADODB.Recordset") ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Baza & ";Mode=Share Deny None;Persist Security Info=False" AdoConnection.Open ConnectionString RSBaza.CursorType = adOpenStatic RSBaza.LockType = adLockOptimistic RSBaza.Open "SELECT * FROM " & Table & " WHERE " & kritBD, AdoConnection RSBaza.MoveFirst Do While RSBaza.EOF = False RSBaza.Fields("Досылали") = Format(Logrezult.VentData, "dd.mm.yyyy") RSBaza.Fields("Дата") = Format(Logrezult.VentData, "dd.mm.yyyy") RSBaza.Fields("Время") = Logrezult.VentTime RSBaza.Fields("Длительность") = Logrezult.VentInterval RSBaza.Fields("Результат") = Logrezult.VentResaltKod RSBaza.Fields("Описание") = Logrezult.VentResaltText If (Logrezult.VentResaltKod = "0") Or (Logrezult.VentResaltKod = "20") Then '0-ок 20-ошибка разъединения RezTM = Format(Logrezult.VentData, "dd.mm.yyyy") & " " & Logrezult.VentTime RSBaza.Fields("Успешно") = Format(Logrezult.VentData, "dd.mm.yyyy") RSBaza.Fields("Скорость") = Logrezult.VentSkorost RSBaza.Fields("FaxID") = Logrezult.VentFaxID If Period(RezTM) = "DEN" Then RSBaza.Fields("РассылкаДень") = "ДА" ElseIf Period(RezTM) = "NOTCH" Then RSBaza.Fields("РассылкаНочь") = "ДА" End If End If RSBaza.Update RSBaza.MoveNext Loop Set RSBaza = Nothing Set AdoConnection = Nothing End Sub Function GetZadanie(Baza As String, Table As String, Line As Integer) As CurrentZadanie 'берет задание из заданного списка и делает пометку в Списке, 'что задание получено данной линией Dim kritBD As String Dim AdoConnection As ADODB.Connection Dim RSBaza As ADODB.Recordset kritBD = "Выполнено = 'нет'" Set AdoConnection = CreateObject("ADODB.Connection") Set RSBaza = CreateObject("ADODB.Recordset") ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Baza & ";Mode=Share Deny None;Persist Security Info=False" AdoConnection.Open ConnectionString RSBaza.CursorType = adOpenStatic RSBaza.LockType = adLockOptimistic RSBaza.Open "SELECT * FROM " & Table & " WHERE " & kritBD, AdoConnection If RSBaza.RecordCount = 0 Then GoTo NoStr RSBaza.MoveFirst GetZadanie.Number = RSBaza.Fields("Номер") GetZadanie.FaxNumer = RSBaza.Fields("Факс") GetZadanie.Dannie = RSBaza.Fields("Данные") RSBaza.Fields("Выполнено") = Line RSBaza.Update Set RSBaza = Nothing Set AdoConnection = Nothing Exit Function NoStr: GetZadanie.Number = "0" GetZadanie.FaxNumer = "" GetZadanie.Dannie = "" Set RSBaza = Nothing Set AdoConnection = Nothing End Function Sub WriteRezult(Baza As String, Table As String, Number As Integer, Logrezult As LogType5, test As Boolean, finish As Boolean, original As Boolean) 'делает запись в текущем списке рассылки 'test-после тестового прозвона выполнено=да 'не пишется даже при OK или ошибка=20 'finish-при финишном прозвоне выполнено=да пишется всегда Dim kritBD As String Dim AdoConnection As ADODB.Connection Dim RSBaza As ADODB.Recordset kritBD = "Номер = " & Number Set AdoConnection = CreateObject("ADODB.Connection") Set RSBaza = CreateObject("ADODB.Recordset") ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Baza & ";Mode=Share Deny None;Persist Security Info=False" AdoConnection.Open ConnectionString RSBaza.CursorType = adOpenStatic RSBaza.LockType = adLockOptimistic RSBaza.Open "SELECT * FROM " & Table & " WHERE " & kritBD, AdoConnection RSBaza.MoveFirst 'выполнено или нет If test = True Then If (Logrezult.VentResaltKod = "18") Or (Logrezult.VentResaltKod = "20") Or (Logrezult.VentResaltKod = "0") Then Else RSBaza.Fields("Выполнено") = "ДА" End If ElseIf finish = True Then RSBaza.Fields("Выполнено") = "ДА" ElseIf original = True Then If (Logrezult.VentResaltKod = "18") Then ' RSBaza.Fields("Выполнено") = "нет" Else RSBaza.Fields("Выполнено") = "ДА" End If Else If (Logrezult.VentResaltKod = "20") Or (Logrezult.VentResaltKod = "0") Then RSBaza.Fields("Выполнено") = "ДА" Else 'нельзя писать нет!-другая линия не должна звонить по той же записи! ' RSBaza.Fields("Выполнено") = "нет" End If End If 'дослано или нет If (Logrezult.VentResaltKod = "20") Or (Logrezult.VentResaltKod = "0") Then RSBaza.Fields("Дослано") = "ДА" ElseIf (Logrezult.VentResaltKod = "18") Then RSBaza.Fields("Дослано") = "18" End If 'ну и собственно данные из протокола RSBaza.Fields("Дата") = Format(Logrezult.VentData, "dd.mm.yyyy") RSBaza.Fields("Время") = Logrezult.VentTime RSBaza.Fields("Длительность") = Logrezult.VentInterval RSBaza.Fields("Имя_факса") = Logrezult.VentFile RSBaza.Fields("Страниц") = Logrezult.VentPageOK & "/" & Logrezult.VentPageFax RSBaza.Fields("N/F") = Logrezult.VentTypeFax RSBaza.Fields("Результат") = Logrezult.VentResaltKod RSBaza.Fields("Скорость") = Logrezult.VentSkorost RSBaza.Fields("Описание") = Logrezult.VentResaltText RSBaza.Fields("FaxID") = Logrezult.VentFaxID RSBaza.Update Set RSBaza = Nothing Set AdoConnection = Nothing End Sub ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 13:58 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Походу прога пытается получить доступ с записям заблокированным апдейтом. Поставь перед апдейтом обработчик, который обработает эту ошибку, подождет и попробует еще раз. А лучше перед каждым апдейтом запускай транзакцию, тогда все апдейты выстроятся в очередь и следующий не будет пытаться лезть в записи, заблокированные предыдущим. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 14:39 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Да у тебя там вообще нет обработчиков. Поэтому и вылетает. "Ну кто так строит, кто так строит!.." (с) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 14:41 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
А можно привести пример обработчика? И в каком месте? Вы считаете, что вылетает именно сама программа как вещь в себе? У меня приведенные коды могут одновременно выполняться из нескольких программ, вероятность того, что 2 программы единовременно полезут в одну и ту же запись одной таблицы в режиме правки ничтожна мала, т.к. по логике 2 программы не должны досылать факсы по одному и тому же номеру тем более одновременно (если только случайно окажутся две записи с одинаковыми факсами, да еще и досылка по этим записям одновременно одновременно закончится), вероятность одновременного обращения к разным записям даже одной таблицы гораздо больше, т.к. необходимость этих обращений возникает исходя из состояния телефонных линий, а их всего 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 15:27 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. И почитай про inline error handling и outline error handling . Это ключевые слова для поиска. Как по-русски это звучит, не помню. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 16:05 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
А как нибудь так сделать можно? Т.е если вылетели, то идем на ErrHandler, ждем 1с и повторяем попытку обращения к базе. On error будет распространяться на все что под ним? GetZadanie(Baza As String, Table As String, Line As Integer) As CurrentZadanie 'берет задание из заданного списка и делает пометку в Списке, 'что задание получено данной линией Dim kritBD As String Dim AdoConnection As ADODB.Connection Dim RSBaza As ADODB.Recordset goto IterOne ErrHandler: ltime=timer() DoEvent Do If(timer()-ltime)>1 then exit do Loop IterOne: On Error Goto ErrHandler kritBD = "Выполнено = 'нет'" Set AdoConnection = CreateObject("ADODB.Connection") Set RSBaza = CreateObject("ADODB.Recordset") ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Baza & ";Mode=Share Deny None;Persist Security Info=False" AdoConnection.Open ConnectionString RSBaza.CursorType = adOpenStatic RSBaza.LockType = adLockOptimistic RSBaza.Open "SELECT * FROM " & Table & " WHERE " & kritBD, AdoConnection If RSBaza.RecordCount = 0 Then GoTo NoStr RSBaza.MoveFirst GetZadanie.Number = RSBaza.Fields("Номер") GetZadanie.FaxNumer = RSBaza.Fields("Факс") GetZadanie.Dannie = RSBaza.Fields("Данные") RSBaza.Fields("Выполнено") = Line RSBaza.Update Set RSBaza = Nothing Set AdoConnection = Nothing Exit Function NoStr: GetZadanie.Number = "0" GetZadanie.FaxNumer = "" GetZadanie.Dannie = "" Set RSBaza = Nothing Set AdoConnection = Nothing End Function ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 16:52 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Нет, так нельзя. Когда исполнение переходит на метку по ошибке, она считает, что обработка ошибки, это все, что идет потом, и если в обработке тоже произойдет ошибка, то она передается обработчику верхнего уровня, т. е. в обработчик процедуры, из которой она была вызвана. Если и там нет обработчика, то ошибка передается еще выше, и так до уровня ОС и прога вылетает. Выход из обработчика и продолжение исполнения текущей процедуры осуществляется с помощью конструкций: Resume - выполнение продолжается с места, где произошла ошибка Resume Next - выполнение продолжается со следующей строки после ошибочной Resume метка - выполнение продолжается с указанной метки В твоем случае лучше так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 17:16 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Забыл в начале On Error Goto ErrHandler И еще, ползуйся кнопкой SRC , а то твои неформатированные простыни читать невозможно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 17:18 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Ну что ж, попробую сделать указанные изменения во всем программах и во всех местах. Надеюсь, поможет... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.08.2006, 23:09 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Исправляю потихоньку... Я даже так пишу, иначе в районе полуночи секунда может затянуться... Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 00:02 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Лучше вместо Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 10:09 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Вроде все поменял как писал в "новых" программах, за часов 12-15 "вылет" произошел только один раз, и вылетела "старая" программа, в кот.ничего не менял, кот. частично использует DAO, да и то, когда в БД Access-ом полез. С этой программой придется отдельно разбираться. Дело в том что делалась давно и вместо ф-ций там процедуры типа приведенных выше встроены не в ф-ции, а в основной код, а сама логика сложнее, чем у остальных программ. AntonariyЛучше ...оставь просто DoEvents. А еще лучше выведи окошко с предложением повторить или продолжить. А то мало ли какая еще ошибка может возникнуть - возьмет да зациклится. Что вообще означает DoEvents? Если правильно понял, то когда его ставишь, то компьютер лучше себя чувствует, и курсор от мышки не "бесится". Почему не дать задержку в 1с? Надо ж процессам устаканиться перед следующей попыткой. Тем более ошибки возникают не часто, хотя лучше их обрабатывать, т.к. практически в моем случае это приводит -к остановке рассылки факсов по вылетевшей линии (линиям) -к не записи информации в статистику о досланном факсе, т.е. к повторной передаче через короткое время, следовательно ругань ("Что вы нам каждый день по 10 факсов шлете???") По поводу окошек: критерий-бесперебойная работа системы, что с того что в 10 вечера выскочит окошко, а я его в 9 утра увижу. Мое постоянное присутствие рядом с PC не является обязательным параметром. А на случай если уж совсем все плохо предусмотрена программная полная перезагрузка сервера раз в 6 часов по расписанию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 15:02 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
В общем, учи матчасть. С твоей проблемой тебе никто не поможет, вся твоя программа - одна большая проблема. Единственное, что еще могу предложить, это завалить ее нештатными ситуациями, чтобы ошибки повылезали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 15:56 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Ну почему проблема. Она ж не для коммерческого использования. Т.е. не для продажи. А как инструмент для работы, а то что есть глюки - ну есть. Был задан вопрос: почему возникает ошибка при совместном доступе к БД? Ответ был по сути дан на другой вопрос: как обойти ошибку и свести к минимуму потери. По сути это решение, а академического интереса у меня здесь особо нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 17:37 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Дмитрий77Был задан вопрос: почему возникает ошибка при совместном доступе к БД? Был дан ответ:Походу прога пытается получить доступ с записям заблокированным апдейтом. Было дано комплексное решение:Поставь перед апдейтом обработчик, который обработает эту ошибку, подождет и попробует еще раз. А лучше перед каждым апдейтом запускай транзакцию, тогда все апдейты выстроятся в очередь и следующий не будет пытаться лезть в записи, заблокированные предыдущим.Вот именно потому, что Дмитрий77академического интереса у меня здесь особо нетполучается Дмитрий77а то что есть глюки - ну естьОбработка ошибок - краеугольный камень написания безглючных программ. Без понимания тобой основ, я могу до нового года давать советы, а глюки будут только множиться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.08.2006, 23:03 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
По сути: Antonariyquot Было дано комплексное решение:Поставь перед апдейтом обработчик, который обработает эту ошибку, подождет и попробует еще раз. Что и было сделано Antonariyquot а глюки будут только множиться. И описанные глюки исчезли. Antonariyquot А лучше перед каждым апдейтом запускай транзакцию, тогда все апдейты выстроятся в очередь и следующий не будет пытаться лезть в записи, заблокированные предыдущим. А вот здесь можно поподробней. Я так понимаю это устранение причины. Это мне больше нравится. Что такое транзакция , как это в терминах кода VB выглядит? P.S.И не ругайтесь вы на меня. Я в програмировании не профессионал, а любитель. И программы я пишу исключительно для себя и коллег. Обработка ошибок вещь нужная. Но их не всегда можно предусмотреть. Изначально вообще был DOS-овский bat-файл, кот.рассылал факсы по заданному списку. Потом появилась БД, была написана одна линейная (для одной телефонной линии) программа,управляющая драйвером VentaFax, и этих ошибок в принципе возникнуть не могло - их обработку незачем было писать, потом линий стало две, потом добавилать SIP-телефония линий стало 4, сейчас у меня их 9, добавилось программное управление Microsoft Fax via VB, модули управления двумя sip-адаптерами через com-port-ы (MSComm), система усложняется, появляются проблемы, их надо решать, они решаются. Надеюсь, Вы со мной согласитесь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2006, 01:46 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
[quot Дмитрий77] А вот здесь можно поподробней. Я так понимаю это устранение причины. Это мне больше нравится. Что такое транзакция , как это в терминах кода VB выглядит? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.08.2006, 10:37 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
Что за загадочный объект "cn" Наверно тогда уж Код: plaintext 1. 2. 3. 4. 5. И можно на пальцах? Правильно я понимаю, что BeginTrans и CommitTrans страхуют заключенный между ними update от описанных ошибок? Или ошибка все же может произойти? А RollbackTrans вернет тогда программу к тому месту, где находится BeginTrans? И эффект будет тот же, что и в случае Resume IterOne? Описание я прочитал, но все же не совсем ясно: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2006, 01:37 |
|
||
|
Одновременное использование БД Access несколькими программами.
|
|||
|---|---|---|---|
|
#18+
BeginTrans -начать транзакцию, это относиться не к программе, а к базе с которой в данный момент работает данная программа. Если в программе не отработает строчка CommitTrans , из-за ошибки или сам не сделаешь, то изменения в базе не пройдут, RollbackTrans - это грубо говря отмена изменений (принудительно). С Accessом у меня подобное возникало, не скажу, что именно такая ошибка, но то же что-то связанное с блокировками. У меня в цикле шпарило типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Поставил после использования первого раза rst rst.close И после rst.Update тоже rst.close Ошибка пропала. У тебя стоит Set RSBaza = Nothing Попробуй Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.08.2006, 04:18 |
|
||
|
|

start [/forum/topic.php?fid=60&msg=33925777&tid=2165427]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
173ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 229ms |
| total: | 500ms |

| 0 / 0 |
