powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема с ConcurrentHashMap
25 сообщений из 99, страница 3 из 4
Проблема с ConcurrentHashMap
    #38521204
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv2) Кто и откуда добавляет сессии в мапку? Где вызов ConcurrentHashMap.put()? Ни в одном из предоставленных вами колчков кода его нет.

Код: java
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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
public void signInHost(Session session,Packets.HelloServer hello) {
		synchronized (mSignInSemaphore) {
			//Connection mConnection=null;
			CallableStatement mStatement = null;
			ResultSet mResult = null;

			try {
				try{
					
					//mConnection=getDbConnection();
					mStatement = mConnection.prepareCall("CALL SIGN_IN_HOST(?,?,?,?,?,?,?,?)");
					mStatement.setString(1, hello.name);
					mStatement.setString(2, hello.password);
					
                                        ....................................................
					....................................................

					mResult = mStatement.executeQuery();
					mConnection.commit();
					
					if (mResult.next()) {

						if (mResult.getString(1).equals("NOT_REGISTERED")) {
							session.sendData(new Packets.Error(ErrorCodes.INVALID_USERNAME_OR_PASSWORD));
							session.killSession();
						} else if (mResult.getString(1).equals("BUSY")) {
							session.killSession();
						} else if (mResult.getString(1).equals("ONLINE")) {
							session.setSessionId(mStatement.getResultSet().getInt(4));
							session.setLogId(mStatement.getResultSet().getInt(3));
							session.setHostId(mStatement.getResultSet().getInt(2));
							session.sessionType = Session.SessionType.Host;
							session.sendData(new Packets.HelloHost());
							session.setEncryptionKey(hello.password.substring(0, 15));
		
							HOSTS_SESSIONS.put(session.getHostId(), session);
						}

					} else {
						session.killSession();
					}
				}
				catch(SQLException e){
					LogHelper.logError(e, "signInHost");
					session.killSession();
					if(mConnection!=null){mConnection.rollback();}
				}
			} catch (Exception e) {
				LogHelper.logError(e, "signInHost");
				session.killSession();
			}
			finally {
				try {
					//if (mConnection!=null){mConnection.close();}
					if (mStatement != null) {mStatement.close();}
					if (mResult != null) {mResult.close();}
				} catch (SQLException e) {
					LogHelper.logError(e, "signInHost");
				}
			}
		}
    }


...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521225
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
делать запрос в базу захватив лок, это конечно мощно
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521276
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel ,
У меня складывается ощущение, что ваша цель - ни в коем случае не позволить нам оказать вам помощь. Потому что с каждым очередным вашим постом все становится лишь непонятнее Вам попросили сделать две вещи:
1) Показать, как гарантируется уникальность айдишника.
2) Показать, кто и откуда кладет сессии в мапку.
Вы же умудрились написать на каждый из этих вопросов по посту ... но ничего не прояснить.

1) Мы не верим на слово, что у вас все корректно инкрементится. Во-первых, потом что если бы у вас все было хорошо, у вас бы не было этого бага. А во-вторых, потому что качество тех урывков кода, что вы показываете, оставляет желать лучшего. Дайте нам код, который генерирует айдишники .
2) Ответьте наконец на вопрос, кто и когда делает put в мапку с сессиями . Вы мне показали метод signInHost , отлично. Но кто его вызывает ? Из каких потоков он вызывается ? И почему вы синхронизируетесь на mSignInSemaphore ?
Теперь смотрите дальше. Сначала я прошу вас сказать, какие потоки могут изменять мапку с сессиями для конкретного айдишника. Вы отвечаете, что это может сделать только один поток ( 15391534 ). Потом я прошу показать вас код этого "одного потока", т.е. метод Session.run(). Вы отвечаете, что это вот этот код 15391319 . А теперь вы показываете метод signInHost , который тоже изменяет эту мапку. Но я что-то не вижу, что бы этот метод вызывался из Session.run() . Кто и откуда его все таки вызывает? И что это за странный synchronized (mSignInSemaphore) ?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521281
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

А зачем так делать?
session.setSessionId( mStatement.getResultSet() .getInt(4));
session.setLogId( mStatement.getResultSet() .getInt(3));
session.setHostId( mStatement.getResultSet() .getInt(2));
У Вас несколько ResultSet-ов возвращает процедура?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521711
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FDGorloPavel,

А зачем так делать?
session.setSessionId( mStatement.getResultSet() .getInt(4));
session.setLogId( mStatement.getResultSet() .getInt(3));
session.setHostId( mStatement.getResultSet() .getInt(2));
У Вас несколько ResultSet-ов возвращает процедура?

Несколько ResultSet не причем, нет вызовов getMoreResults. Хотя в документации и написано
getResultSet(): Retrieves the current result as a ResultSet object. This method should be called only once per result.
проблем при множественном вызове вроде не должен вызывать.
GorloPavel а можно SIGN_IN_HOST показать?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521878
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvДайте нам код, который генерирует айдишники[/b].
Все же элементарно! К примеру есть таблица, в ней 3 поля. host_id(автоинкриментное), host_name, host_password. Делается чертов
Код: sql
1.
SELECT host_id FROM hosts WHERE host_name=name AND host_password=password

. Вот этот самый host_id и есть ключ в мапе. Он и возвращается в ResultSet-e

cdtyjv Ответьте наконец на вопрос, кто и когда делает put в мапку с сессиями. Вы мне показали метод signInHost, отлично. Но кто его вызывает? Из каких потоков он вызывается? И почему вы синхронизируетесь на mSignInSemaphore?

Из этого же самого потока! signInHost просто метод в другом классе. mSignInSemaphore нужен для того чтобы эту функцию выполнял только один поток в один момент времени. Представьте что сразу 5к клиентов одновременно пытаются авторизироваться.

cdtyjvНо я что-то не вижу, что бы этот метод вызывался из Session.run()
Код: java
1.
mPacketSplitter.splitData(dataBuffer, receivedBytes);


Session реализует интерфейс OnPacketSplitter. В методе просто обрабатываются полученные байты данных и там же вызывается метод signInHost
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521880
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FDGorloPavel,
А зачем так делать?

Уже поправил.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521936
0FD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

А почему не может быть так, а сразу ConcurrentHashMap<Integer, Session> теряет элементы:

mStatement.executeUpdate(String.format("DELETE FROM hosts_online WHERE host_id=%s",getHostId())); <-- тут не удалили
...
Hub.HOSTS_SESSIONS.remove(getHostId()); <-- удалил

тогда SIGN_IN_HOST добавляет запись в hosts_online с одним host_id, а возвращает другой?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38521941
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FDА почему не может быть так, а сразу ConcurrentHashMap<Integer, Session> теряет элементы:

mStatement.executeUpdate(String.format("DELETE FROM hosts_online WHERE host_id=%s",getHostId())); <-- тут не удалили
...
Hub.HOSTS_SESSIONS.remove(getHostId()); <-- удалил

тогда SIGN_IN_HOST добавляет запись в hosts_online с одним host_id, а возвращает другой?
По-моему это очень вероятный вариант. Я о нем тоже вчера думал. Стоит проверять количество измененых записей.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522027
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczПо-моему это очень вероятный вариант. Я о нем тоже вчера думал. Стоит проверять количество измененых записей.
Не совсем понял о чем вы? getHostId() всегда вернет верный id.

Код: java
1.
2.
3.
4.
5.
6.
7.
mStatement = mConnection.createStatement();
mStatement.executeUpdate(String.format("DELETE FROM hosts_online WHERE host_id=%s",getHostId()));
mStatement.executeUpdate(String.format("UPDATE connections_log SET disconnect_date_time=NOW() WHERE id=%s",getLogId()));
					
mConnection.commit();

Hub.HOSTS_SESSIONS.remove(getHostId());
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522035
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
0FDтогда SIGN_IN_HOST добавляет запись в hosts_online с одним host_id, а возвращает другой?

Не понял. В процедуре простая строка. При авторизации всегда вернет то что нужно. ID записи.
Код: sql
1.
2.
SELECT host_id INTO host_id
FROM hosts WHERE host_name=name AND host_password=password;
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522053
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelНе совсем понял о чем вы? getHostId() всегда вернет верный id.

Все программы всегда работают правильно. Тут уже несколько спорных мест в коде указали. Причем в простейшем логе можно было бы всё видеть. А у вас логирование, судя по всему, отсутствует и это некоторое принципиальное решение. Поэтому можно прекращать гадать на кофейной гуще. Код кривой. Сценариев которые могут привести к ошибке несколько. Вы по каждому просто отвечаете, что такого не может быть. Ну, не может, так не может. Вам виднее. Смысл тогда на форуме о чем-то спрашивать если вы сами всё знаете?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522355
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде проблема нашлась. Спасибо за наводку!

Код: java
1.
2.
3.
4.
5.
6.
7.
mStatement = mConnection.createStatement();
mStatement.executeUpdate(String.format("DELETE FROM hosts_online WHERE host_id=%s",getHostId()));
mStatement.executeUpdate(String.format("UPDATE connections_log SET disconnect_date_time=NOW() WHERE id=%s",getLogId()));
					
mConnection.commit();

Hub.HOSTS_SESSIONS.remove(getHostId());



Вообщем проблема в том что в момент(вернее после) DELETE FROM hosts_online WHERE host_id, до Hub.HOSTS_SESSIONS.remove(getHostId()) Может произойти SIGN_IN_HOST и тогда при Hub.HOSTS_SESSIONS.remove(getHostId()) удаляется активная сессия. Происходит это если у клиента нестабильное подключение и происходят постоянные реконнекты.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522364
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока просто Hub.HOSTS_SESSIONS.remove(getHostId()); поместил выше запросов в БД... Завтра буду рефакторить по полной. Ждите новых постов ;) Всем ОГРОМНОЕ СПАСИБО!
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522371
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если DELETE FROM hosts_online WHERE host_id=%s не отработает? Тут надо не рефакторить а полностью переписывать имхо.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38522880
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelchabapokВот вы пишите, что у вас sessionId - это автоинкрементное поле в базе.
Смотрите выше. В других случаях естественно используется last_insert_id .

Тут какое-то нездоровое общение. С подобной проблемой топик должен быть переполнен от кода, но кода вы не приводите практически. Те разрозненные куски кода, которые есть - это как обрывки. А как можно найти ошибку без кода - мне не понятно. И что там выше я должен был найти - мне тоже непонятно, потому что поиском по last_insert_id ничего не находится кроме моего сообщения. Вы бы хоть дали ссылку на нужное сообщение. У меня вообще создается впечатление, что вы не очень заинтересованы в том, чтобы вам помогли. Поэтому предположу, что вы last_insert_id используете как-то неправильно.

В каких "других случаях" используется last_insert_id? Почему в других а не во всех и не в данном случае? Кстати, из того кода что вы привели -- вы делаете SESSONS_COUNT++, а кто делает декремент? Если это делается в другом потоке, то это неправильно и так делать нельзя, потому что ++ неатомарно даже на волатилах.

вам нужно что-нибудь почитать про принципы написания многопоточных программ. В гугле полно инфы.

И чтобы вам помогли, надо привести ключевые участки кода. Все. Иначе это все гадание и телепатия. :)
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38523350
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokGorloPavelпропущено...

Смотрите выше. В других случаях естественно используется last_insert_id .

Тут какое-то нездоровое общение. С подобной проблемой топик должен быть переполнен от кода, но кода вы не приводите практически. Те разрозненные куски кода, которые есть - это как обрывки. А как можно найти ошибку без кода - мне не понятно. И что там выше я должен был найти - мне тоже непонятно, потому что поиском по last_insert_id ничего не находится кроме моего сообщения. Вы бы хоть дали ссылку на нужное сообщение. У меня вообще создается впечатление, что вы не очень заинтересованы в том, чтобы вам помогли. Поэтому предположу, что вы last_insert_id используете как-то неправильно.

В каких "других случаях" используется last_insert_id? Почему в других а не во всех и не в данном случае? Кстати, из того кода что вы привели -- вы делаете SESSONS_COUNT++, а кто делает декремент? Если это делается в другом потоке, то это неправильно и так делать нельзя, потому что ++ неатомарно даже на волатилах.

вам нужно что-нибудь почитать про принципы написания многопоточных программ. В гугле полно инфы.

И чтобы вам помогли, надо привести ключевые участки кода. Все. Иначе это все гадание и телепатия. :)

Проблема решена. SESSONS_COUNT++ и SESSONS_COUNT-- в разных потоках. Какие проблемы могут возникнуть и как правильно сделать?
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38523422
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavelПроблема решена. SESSONS_COUNT++ и SESSONS_COUNT-- в разных потоках. Какие проблемы могут возникнуть и как правильно сделать?
AtomicInteger
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38523508
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

Как сказал кто-то выше - следите за руками!

Например так:
потоки А и Б работают одновременно.
В вашу переменную записана двойка - т.к. есть два потока. Потоки завешаются одновременно.

1. Поток А загружает в регистр процессора из ячейки памяти значение переменной. В регистр попала двойка.
2. Поток Б загружает в регистр процессора из ячейки памяти значение переменной. В регистр попала двойка.
3. Поток А делает декремент своего регистра. Теперь в регистре потока А единциа.
4. Поток Б делает декремент своего регистра. Теперь в регистре потока Б тоже единциа.
5. Поток А записывает свой регистр в память и завершает работу.
6. Поток Б записывает свой регистр в память и завершает работу.

итог - завершилось два потока, а декремент по факту произошел на 1 а не на 2, и в вашей переменной единица.

Или так:
Поток А завершает работу, а в это время в потоке где у вас accept вы делаете ++ (назовем его поток Б). В переменной единица.
1. Поток А загружает в регистр процессора единицу
2. Поток Б загружает в регистр процессора единицу.
3. поток А делает декремент, получается 0.
4. поток Б делает ++, получается 2.
5. поток А записывает свой регистр в память
6. поток Б записывает свой регистр в память

итог - один поток завершился, один создался, а в вашей переменной 2.
Или -- то же самое, но в последнем примере 5 и 6 поменяны местами. Итог - один поток завершился, один создался, а в вашей переменной 0.

Общий итог - если нет опыта создания многопоточных приложений, то вот так сходу, даже если кажется что все заработало, скорей всего есть еще некоторое кол-во скрытых ошибок, которые обязательно проявят себя при определенном стечении обстоятельств. Описаная выше проблема - одна из тех, с которыми сталкиваешься при написании многопоточных приложений (есть и другие), подобная ситуация называется состояние гонки данных (race condition). Так и гуглите...

И вот сюда тоже сходите ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%B3%D0%BE%D0%BD%D0%BA%D0%B8
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525003
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,

Пожалуйста, хватит пытаться вырезать гланды через анальное отверстие, откажитесь от блокирующей записи в базу и получения идентификатора сессии из БД, для уникальных идентификаторов придуман был GUID, его и используйте до или вообще вместо обращения к БД.
А если уж так необходимо организовать хранение информации о текущих сессиях в базе - используйте для общения с БД отдельную очередь, обрабатываемую отдельным потоком.
Основные "рабочие" потоки могут добавлять в очередь "задачи" для отработки их в базе.

Я понимаю, что Вы взялись за интересную для Вас задачу, тем не менее, прежде чем отрабатывать подобные вещи, нужно, как минимум, продумать общую архитектуру решения, продумать механизмы взаимодействия между слоями, а уж потом начинать "ваять"...
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525009
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Kuznetsov ,
Ну я бы не был так категоричен. Во-первых, автор учится. Ошибается, да. Не всегда может внятно объяснить, что к чему, да. Но не ошибается только тот, кто ничего не делает. Важен не сам факт ошибки или кривой архитектуры, а то, какие выводы автор из этого всего сделает.
Во-вторых, с вашими предложениями по гуидам и работе с базой с одного потока можно поспорить. Все существующие СУБД нормально умеют выдавать уникальные значения, будь то сиквенсы в Оракле, или же айдентити в SQL Server / MySQL. И у автора вроде бы нет с этим особых проблем. Ну да ладно, как генерировать id - это переливание из пустого в порожнее, тут и тот, и тот варианты подойдут. А вот работать с базой через один поток - это решение едва ли может назвать хорошей архитектурой. Масштабируемость на нуле, любой затуп, например долгое ожидание блокировки на определнной строке в СУБД, намертво вешает всю систему. Как по мне, с отсутствием деталей задачи автора, мне здесь видится хорошим решением банальнейшие пессимистичные блокировки:
1) Завинчиваем уровень изоляции до REPEATABLE_READ;
2) Потом делаем SELECT id FROM table FOR UPDATE в явной транзакции;
3) Абсолютно безопасно меняем сессию как нам угодно;
4) Закрываем транзакцию.
Это и с точки зрения многопоточности легко сделать, ибо почти весь гемор автоматом уходит на сторону СУБД, и масштабируемость будет приемлемая.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525197
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv,

Согласен, что автор учится, тем не менее, создаётся впечатление, что слушает, но не слышит...

По поводу одного потока для обработки очереди - конечно это кривоватый подход, тем не менее, что мешает сделать несколько потоков для обработки очереди и использовать пул соединений вместо одного?
Естественно, что даже это не избавляет от проблем блокировки на уровне одного конкретного соединения.

Возьмём к примеру боевые, промышленные серверы приложений - в них уровень работы с БД вынесен в отдельные очереди и потоки, т.е. бизнес логика отвязана от базы данных и помещает задачи БД в очередь, которая и обрабатывается этими самыми потоками. Это в качестве примера...

Можно даже сделать "финт ушами" и в очередь помещать DML запросы, а выборки делать непосредственно из потока бизнес логики. Но и при этом можно нарваться на неприятности... Ну т.е. вывод один - в системах подобного масштаба мелочей не бывает и нужно тщательно продумывать все детали.

По поводу использования GUID я не зря сказал, потому как, судя по предварительным результатам обсуждения, проблема как раз в связке бизнес логики и БД в разрезе разрозненных потоков. В данном случае генерация уникального идентификатора на стороне бизнес логики, а не БД поможет решить проблему идентификации уникальной сессии. Как пример - тот-же идентификатор сессии в servlet контейнерах...
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525741
GorloPavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята. Нет никакой проблемы с id-шниками и т.д у меня. Сейчас все работает как надо. Всем огромнейшее СПАСИБО! Вопрос в следующем... К примеру у меня 2000 подключений. И вдруг они разом отключаются, мне нужно зарегистрировать это в БД. Сейчас при таком раскладе у меня сразу будет 2000 подключений к БД(та самая функция removeSession которую мы тут обсуждали). Я же хочу чтобы на это дело потоки вставали в очередь... Просто реально нет времени объяснять как устроена и что у меня тут за система. Можете посмотреть по моим темам. Еще раз спасибо!
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525756
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GorloPavel,
каждый поток пусть сам пишет в БД.
Так же как это делает банальный JSP при модели сервлет-поток.
События конца юзер-сессии не так чАсты, чтобы беспокоиться.
...
Рейтинг: 0 / 0
Проблема с ConcurrentHashMap
    #38525930
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123GorloPavel,
каждый поток пусть сам пишет в БД.
Так же как это делает банальный JSP при модели сервлет-поток.
События конца юзер-сессии не так чАсты, чтобы беспокоиться.Повбывавбы.
Нет, достаточно количество ядер, конечно и сотни одновременных обновлений одной таблицы разрулят, но за подход - повбывавбы
...
Рейтинг: 0 / 0
25 сообщений из 99, страница 3 из 4
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема с ConcurrentHashMap
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]