2010-01-16 2 views
2

Я создаю приложение Twitter, и каждый раз, когда пользователь обновляет страницу, он перезагружает новейшие сообщения из Twitter и сохраняет их в локальной базе данных, если они уже не были созданы ранее. Это хорошо работает в среде разработки (база данных: sqlite3), но в рабочей среде (mysql) она всегда создает сообщения снова, даже если они уже созданы. Создание сообщенияОтладка Rails в рабочей среде

проверяется twitter_id, что каждое сообщение имеет:

msg = Message.find_by_twitter_id(message_hash['id'].to_i) 
if msg.nil? 
    # creates new message from message_hash (and possibly new user too) 
end 
msg.save 

По-видимому, в производственной среде, он не в состоянии найти сообщения от щебета ид по какой-то причине (когда я смотрю на базе данных она была избавлена все атрибуты правильно раньше).

С этим длинным введением, я думаю, мой главный вопрос: как мне отладить это? (Если у вас уже есть ответ на основную проблему, конечно же :) Когда я смотрю в production.log, это только показывает, что-то вроде:

Processing MainPageController#feeds (for 91.154.7.200 at 2010-01-16 14:35:36) [GET] 
Rendering template within layouts/application 
Rendering main_page/feeds 
Completed in 9774ms (View: 164, DB: 874) | 200 OK [http://www.tweets.vidious.net/] 

... но не запросов базы данных, logger.debug тексты или все, что могло бы помочь мне найти проблему.

+1

Почему вы не используете MySQL в разработке тоже, из интереса? –

+0

Что означает хэш сообщений? – Eimantas

+0

John, sqlite3 поставляется по умолчанию ... Но, возможно, будет проще использовать такую ​​же базу данных как в разработке, так и в производстве. – JussiR

ответ

9

Вы можете изменить уровень ведения журнала производства, установив уровень журнала в конфигурации/окружающей среды/production.rb

config.log_level = :debug 

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

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

это может быть из-за нескольких соединений доступ к MySQL?

Если записи твиттера еще не зафиксированы, запрос для них из другого соединения не будет возвращать их, поэтому, если ваш запрос для них вызывается перед фиксацией, то вы их не найдете, и вместо этого снова вставьте те же записи. Это гораздо более вероятно произойдет в производственной среде со многими пользователями, чем с вами только тестирование на sqlite.

Поскольку вы используете mysql, вы можете использовать уникальный ключ для идентификатора twitter для предотвращения дублирования, а затем использовать исключение ActiveRecord, если попытаетесь вставить обман. Но это означает обработку ошибки, которая не является хорошим способом справиться с этим (хотя я рекомендую сделать это как средство резервного копирования для предотвращения дублирования - mysql подходит для этого, используйте его).

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

+0

Спасибо за код отладки. Когда я просматривал журнал, я нашел проблему: по какой-либо причине в базе данных production/mysql он всегда сохраняет один и тот же файл twitter_id в сообщениях (2147483647), что даже не является допустимым идентификатором для любого сообщения. Dunno, почему я не заметил этого раньше. На самом деле, в production.log он показывает правильные идентификаторы сообщений о создании, такие как: [4; 36; 1mMessage Create (0.4ms) [0m [0; 1mINSERT INTO 'messages' (' retweets', 'twitter_id', ...) VALUES (0, 7852958107, ...) ... но в базе данных все данные twitter_id: s изменены до 2147483647. – JussiR

+1

Идентификатор twitter явно слишком велик для столбца - MySQL по умолчанию принимает недопустимые значения для столбцов и усекает их до ближайшего значения. Включите SQL_MODE в нечто вроде «TRADITIONAL», чтобы предотвратить это неправильное поведение. Чтобы устранить проблему, измените столбец на более крупный тип int или что-то еще. О да, и всегда проверяйте свое приложение с тем же сервером баз данных (и всем другим программным обеспечением), что и производство, - ничего не стоит делать. – MarkR

+0

Спасибо! Это решило проблему. Не удалось найти способ изменения SQL_MODE (в myPHPAdmin). Хотя, вероятно, есть команда SQL для этого? В любом случае, проблема решена, я счастлив. :) – JussiR

1

Я столкнулся с подобной проблемой при сохранении электронных писем в базе данных, я согласен с Эндрю, установить уровень журнала для отладки для получения дополнительной информации о том, что именно происходит.

Что касается актуальной проблемы, вы можете попробовать добавить уникальный индекс в базу данных, которая предотвратит сохранение двух элементов с теми же параметрами. Это похоже на validates_uniqueness, но на уровне базы данных и очень эффективно: Mysql Constraign Database Entries in Rails.

Например, если вы не хотите, чтобы в вашей базе данных не было объектов сообщений с дублирующимся текстом и дублированный идентификатор твитера (что означало бы, что тот же человек написал твиттер того же текста). Затем вы можете добавить к вашей миграции:

add_index(:message, [:twitter_id, :body] , :unique => true) 

Это занимает небольшое количество времени после того, как вам сказать, объект в Rails, чтобы сохранить, прежде чем он на самом деле попадает в базу данных, то будет возможно, почему запрос для идентификатора Безразлично Еще ничего не найти.

+0

Спасибо, я должен изучить это. Странно то, что даже когда я сделал обычную «validates_uniquity: twitter_id», он все равно создал сообщения и дал им все тот же twitter_id (как описано в комментарии к ответе Эндрюса). пс. извините, если мое объяснение сбивает с толку, но twitter_id ссылается на собственный идентификатор сообщений в базе данных twitter (так что это не идентификатор пользователя). – JussiR

+0

Я знаю, что проблема решена, и я рад, но я чувствую, что должен упомянуть, что validates_uniqueness ужасно - это не работает, поскольку отставание между его проверкой и фактическим фиксацией позволяет обманывать довольно легко. –

+0

Полезно знать. Мне нужно будет начать использовать метод, показанный выше. – JussiR

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