2011-12-21 6 views
0

У меня есть приложение, получающее сообщения из разных источников (чаты и частные чаты). можно открыть несколько экземпляров приложения, а конечный результат должен быть что-то подобное следующему сценарию:Управление журналами чатов, производительность

Desired data flow

В настоящее время каждое приложение сохраняет журналы в каталоге, имя которого учетная запись, используемая для входа на чат-сервер; в то время как это не проблема для частных источников чата (уникальная для каждого экземпляра приложения), бесполезно, чтобы одни и те же журналы сохранялись несколько раз, в отношении общих чатов. Журналы сохраняются в текстовом формате, поэтому их можно получить и прочитать, не прокладывая их через приложение.

Если я не сохраняю журналы в отдельных папках, я могу получить исключения I/O из-за одновременного доступа к одному и тому же файлу из нескольких процессов, и мне нужно будет проверить, будет ли строка, подлежащая сохранению, hasn ' t уже были написаны другими приложениями. Мне нужно оптимизировать всю операцию и попытаться сохранить читаемость кода.

Кроме того, мой текущий подход к написанию линий заключается в следующем:

public void Write(string message) 
    { 
     using (var writer = new StreamWriter(_fileName, File.Exists(_fileName))) 
      writer.WriteLine(message); 
    } 

Что, учитывая, что журналы постоянно написано, может быть не самым эффективным решением.

Подвел, мои вопросы:

  • Как создать уникальную папку базу данных/журналов, сохраняя их формат (обычный текст), но решения вышеупомянутых дублей/проблемы доступа?
  • Как улучшить, если возможно, метод записи? Помните, что журналы должны быть постоянно записаны, но закрытие StreamWriter, когда приложение выходит, не будет правильным решением, так как приложение предназначено для работы в течение длительного времени.

спасибо.

+0

Почему вы не используете рамки протоколирования, таких как log4net? –

+0

@AaronMcIver: Хотя это справедливо, это может не помочь обойти несколько экземпляров, записывающих недвойственные данные в один файл. – R0MANARMY

+1

Ваш эскиз предполагает, что дублирующие журналы из Chatroom 1 будут рассматриваться только как дубликаты в хранилище журналов. Это так? Если да, вы не сможете дедуктировать их с двумя несвязанными экземплярами приложения. –

ответ

0

Если честно, если бы я был вами, я бы посмотрел на уже существующие рамки с открытым исходным кодом, например. NLog. Он достаточно быстр и поддерживает асинхронное ведение журнала, поэтому он должен делать именно то, что вы ищете.

0

Не уверен, если я должен написать это как ответ или комментарий, но, возможно, потребуется номер:

Вы упомянули свой эскизе желаемого результата, но, как я сказал, что это помешает вам deduping если вы не связывайте экземпляры. Так вот что я хотел бы предложить:

  • создается два приложения: LogWriter, который является точкой и сидит в нижней части эскиза
  • LogProcessor, что экземпляры приложения в вашем эскизе.
  • При запуске экземпляра LogProcessor он запускает LogWriter или подключается к нему, если он уже запущен.
  • LogProcessor обрабатывает входящие запросы журнала, возможно, препроцессы их, если вам нужно это сделать, а затем отправляет их в LogWriter как кортеж Timestamp, ChatroomID, UserID (не обязательно быть уникальным), текст и, возможно, хэш для более легкая дедупликация.Вычисление хэша в случаях позволяет более эффективно использовать нескольких ядер
  • LogWriter хранит список висит отсортированный по временной метке, содержащим хеши, поэтому она способна быстро отбросить повторяющиеся элементы
  • Для остальных предметов, LogWriter определяет путь к файлу. Если поток уже открыт для этого пути, он записывает элемент, обновляет временную метку LastUsed в этом потоке и делается
  • Если поток не открыт, LogWriter открывает один, а затем записывает.
  • Если максимальное количество потоков достигнуто, оно закрывает самый старый поток (как по вышеупомянутой временной отметке LastUsed) и вместо этого открывает необходимый новый поток.
1

Я бы придумал простое решение, которое может быть уместным для ваших нужд, но не совсем уверенное.

Моим подходом было бы использовать один файл для каждого сеанса/комнаты чата. Если такой сеанс запущен, приложение пытается создать/открыть этот файл и создать блокировку записи для этого файла. Если он получает исключение IOException (поскольку файл заблокирован), он может просто полностью пропустить регистрацию.

+0

Кажется довольно простым и подходящим решением, за исключением того, что я мог бы реализовать другую блокировку, чтобы избежать ретрансляции при систематической обработке исключений. Благодаря! – user1098567

0

Возможно, измените дизайн приложения таким образом, чтобы регистратор был прикреплен к чату не к пользователю.

Когда пользователи входят в чат, чат будет передавать объект регистрации пользователю.

Таким образом, все пользователи будут использовать один и тот же регистратор. Затем возникает проблема: 1 потребитель (регистратор) и несколько производителей (все те пользователи, которые хотят регистрироваться).

См my reply на этот пост:

Write to FileOutputStream from multiple threads in Java

здесь

https://stackoverflow.com/a/8422621/1007845

Смежные вопросы