Commit Graph

396 Commits

Author SHA1 Message Date
Steve Howell d740d7c082 Show user-uploaded avatars on the website.
Show user-uploaded avatars on the website for users who have
UserProfile.avatar_source == 'U'.  (Continue to show gravatars
for other users.)  This includes the home page, the visible-phone
div, and the settings page.

This fix does NOT address a few things:
* There is no GUI to actually upload user images yet on the website.
* The !gravatar syntax in bugdown will continue to show gravatar images
  only.
* We are not changing identicon behavior.

(imported from commit 9f5ac0bbe21ba56528048233aab2430e4dd431aa)
2013-06-12 15:34:51 -04:00
Zev Benjamin 03b40d180c Add logging filter for checking that the app is actually deployed
(imported from commit 77bd7e008fdea4033e18a91d206999f9714e0f74)
2013-06-10 14:59:29 -04:00
Zev Benjamin 7d999160ab Move logging rate-limiting code
The new file can't be called logging.py because then it would be
annoying to import the system logging module within it.

(imported from commit 71d116e4be98d45b09dda049a43142a82647b727)
2013-06-10 14:59:29 -04:00
Leo Franchi f4132ace48 Fix bankruptcy event sent to graphite
(imported from commit b016ab41ddc2636b76a49c9eb33b7becd387557d)
2013-06-10 09:17:43 -04:00
Tim Abbott 16ffd539af Fix computation of original pre-editing message contents.
(imported from commit ebbdc2580cd502bfb2fb07fa144ab6f815b960e7)
2013-06-06 14:18:49 -04:00
Tim Abbott 871e1b65d3 Don't highlight message edit diffs on prod for now.
(imported from commit 2bfba46c42216f5b4e83098f22291a089d527d7d)
2013-06-06 10:40:17 -04:00
Tim Abbott 0ad1094e45 bugdown: Add custom per-realm filters to linkify certain strings.
I've tried to do this in a way that's scalable and easily configured,
so that we can add new such filters for customers on-demand without
needing to add anything other than a bit of configuration.

Once we're confident in the arguments to this system, I think we'll
want to move the regular expression lists into the database so that we
don't need to do a prod push to modify the regular expression lists.

The initial set of regular expressions are:
(1) Linkifying e.g. "trac #224" in the Humbug realm, so we're exercising this code.
(2) The various ticket number things CUSTOMER7 uses for the CUSTOMER7 realm.

(imported from commit 992b0937b9012c15a7c2f585eb0aacb221c52e01)
2013-06-05 17:48:21 -04:00
Leo Franchi b815d7ea83 Properly calculate expiry of keys we add to Redis
(imported from commit 42fda34ed1cd1eb9411defa1c0cbf53ef0de7a7b)
2013-06-05 16:49:30 -04:00
Zev Benjamin 2f7f0da27f Use a per-deployment memcached key prefix
Some cache keys used by Django (like sessions) will not have the key
prefixes, but those values shouldn't change across most restarts.

(imported from commit 2fe61028111fe9d5700432214a611b3341412654)
2013-06-05 16:33:43 -04:00
Zev Benjamin 826b895a2c Avoid using djcache directly
(imported from commit 2a8f0135c7e31ecc30628420e521c8f708c656c5)
2013-06-05 16:33:43 -04:00
Leo Franchi 92256ab48f Add a TESTING_DEPLOYED settings key, and don't send stats for it
(imported from commit cd73317814a240f7df180f546a9eb6937bb368bb)
2013-06-05 12:57:47 -04:00
Zev Benjamin 4bf3cf1c67 Fix whitespace
(imported from commit 27ad5cda6ce439f81fb0ab231ef43303f2d70736)
2013-06-04 19:33:20 -04:00
Zev Benjamin 5a1f036db3 Use Diff Match Patch instead of difflib for HTML diffing
Diff Match Patch provides more human-readable diffs.  For example,
try replacing "mouse" with "sofas".

(imported from commit 7ced81202ce85d5ef69888c59912e3e44c38cfc8)
2013-06-04 18:18:36 -04:00
Zev Benjamin 0c20f48636 Show changes to edited messages using color highlighting
I didn't use red and green for fear of it not being visible to
color-blind users.  We may need to tweak the colors.

(imported from commit 59c4f1dac549a248783e4c3b3ec472d8cb690df5)
2013-06-04 18:15:45 -04:00
Zev Benjamin df53f54cbd Add library to diff HTML fragments and mark changes
I would really like to parse the HTML we produce from the library to
ensure that we don't generate malformed-HTML.  This is unfortunately
hard because we both want pretty strict parsing and we want to parse
html5 fragments.  For now, we just do a basic sanity check.

We also may want to switch to Google Diff-Match-Patch, as that can
clean up the resulting diffs.

(imported from commit 3772f92135cfd7423c335335f861f2c11462a8db)
2013-06-04 18:15:45 -04:00
Leo Franchi 0b5b1dafc4 Add a rate limiting system to our backend
(imported from commit a1218618918b4dedc77307e2f277665e7dd8fa22)
2013-06-04 09:43:09 -04:00
Jessica McKellar a63b0e31a7 Say if a realm is open in the internal signups Humbug.
(imported from commit 5745f3b2fbfbbdc2681628ef1ccb637cc1abb9f3)
2013-06-02 15:12:28 -04:00
Jessica McKellar 79d494282d Use a case-insensitive wrapper around retrieving a realm by its domain.
We were previously able to create realms for different casings of the
same domain.

(imported from commit c13a86c9eb9fb4934bebcda7a578e2a071dd1962)
2013-06-02 15:12:28 -04:00
Jessica McKellar 83a8ed048f Remove unused imports in zephyr/lib/.
(imported from commit 54fa64f34d29ede939d18f3834249b7bff4490e5)
2013-06-02 15:12:27 -04:00
Jessica McKellar 048a53c1ce Make do_create_realm aware of restricted_to_domain.
(imported from commit bee8d79cd5f5d4165e2a573eb3a91123857be6cd)
2013-06-02 15:12:27 -04:00
Jessica McKellar 67a25614df Remove unused reply argument to do_create_realm.
(imported from commit 6f56c0748a989a8d7163d20f6d9d243c8d96ce87)
2013-06-02 15:12:27 -04:00
Leo Franchi a906e1609d Remove 'PM' from missed message subject as we also email you on @-notifications
(imported from commit 0993bae5b6a1e40b462a314c41bd5c2d47b4bc8c)
2013-05-31 15:54:57 -04:00
Steve Howell 303b8174ac Fix trailing whitespace in a couple Python files.
(imported from commit a8338773aa4ff10add6f06c699b395890b9ed3ee)
2013-05-31 15:25:35 -04:00
Leo Franchi 56af48cd50 Split wildcard mentions from personal mentions, only email on personals
(imported from commit 18971d9e40dd2c93ef9c30edc963da33e3c65309)
2013-05-31 12:24:31 -04:00
Tim Abbott 47b4283c4b Only use numbers and letters in our API keys.
(imported from commit f845fd092695286b83a2e4c9a5708df778c5b770)
2013-05-30 16:42:14 -04:00
Keegan McAllister 371d0dbaa0 Identify app.js source map using a special comment
If we're going to minify third party code, the size heuristic may not hold
anymore.

(imported from commit 78ada1fee1446e78b3b1ad299ee3e975d1cd9002)
2013-05-30 13:51:46 -04:00
Keegan McAllister 5aafdc7cf9 Set input language for Closure Compiler to ECMAScript 5
Some of the third-party files use constructs not valid in ECMAScript 3 (the
default).

(imported from commit 9292bf23a4860353944c18a6f413b4828cc63e11)
2013-05-30 13:51:46 -04:00
Tim Abbott 2b1799b71c bugdown: Fix handling of twitter-format links that aren't actually tweets.
(imported from commit 60512147d8d303ff07cf1e86306fd14b1490e708)
2013-05-30 10:29:41 -04:00
Tim Abbott abd9e4e635 Use proper randomization when generating new API keys.
Previously we were generating API keys deterministically using a hash
of the user's email address; this is clearly not a good long-term
approach.

(imported from commit 14d0c7c9edbc45b3ae1d17a43765ad9726338d4d)
2013-05-29 15:11:24 -04:00
Leo Franchi 81bb2603eb Replace statsd.py with a call to statsd
(imported from commit 086b9c565b0e3bc88aa3dcd0fb76024ec21d8556)
2013-05-29 09:59:28 -04:00
Leo Franchi bd921c6a04 Allow mentions in PMs
(imported from commit 4d354eb3abb153706a577312724fa40fd2559f92)
2013-05-29 09:48:14 -04:00
Tim Abbott 2de2491021 Disabled embed.ly support, for now.
We get too many error reports from it, which is bad for us actually
fixing the other errors that we do have.

(imported from commit 8442fe4251adb15a01b4e61ebcd07bc270b08631)
2013-05-28 11:50:56 -04:00
Leo Franchi c528e3d960 Handle multiple users with the same fullname or shortname in @-completions
(imported from commit 3d60b657ae975e5dcdfc383f431eb8c8dee2c40a)
2013-05-28 10:17:05 -04:00
Leo Franchi d25d52cf00 Batch messages into logical groups in emails, like the web interface
(imported from commit 5c771f7aafc3972c8f0dd1dc329535233f01ee7a)
2013-05-24 21:23:59 -04:00
Leo Franchi 65b247edec Add a event_queue gc hook for missed messages
(imported from commit a799abb35a9622e6aa59e9499cab3281ccb6859f)
2013-05-24 21:23:59 -04:00
Leo Franchi 81058f5f9b Reset our 24hr email blackout when a user logs in
(imported from commit 93bed7c4d049ba4d7b30d2e02fbbe0d2debca6f8)
2013-05-24 21:23:59 -04:00
Leo Franchi e5b1e16885 [schema] Make last_reminder field nullable
(imported from commit e7d14c222d64ac317fc96d0c6bb17220aa6ba097)
2013-05-24 21:23:58 -04:00
Leo Franchi 1a0eefdaa5 Send missed message email on @-notifications
(imported from commit 4c29662ae45fd5e5932b5a6029b90afc7efbbd09)
2013-05-24 21:23:58 -04:00
Leo Franchi b548538a98 [manual] Send UserMessage flags in get_events updates
This commit must be deployed in a separate step from the previous [manual]
commit

(imported from commit c6f00e217062790fce8380f61f82ea8824fb3722)
2013-05-24 21:23:58 -04:00
Leo Franchi 3c81664641 Calculate mentions in a message server-side, and save as UserMessage flag
(imported from commit a3a868a8c6f48b68010108e0ec18ca65b7f0d498)
2013-05-24 21:23:58 -04:00
acrefoot 9454683108 [manual] Send new-stream invitations using a bulk database query
Messages that get sent out when someone subscribes many people to a new stream each
cause individual database queries (and their associated transactions). With the patched
bulk_create (which sets the .id on created objects), we can reduce this query down to a constant
number of queries on the Message and UserMessage tables.

Note for deployment (local dev, staging and prod):
you must be running a patched django, found here: https://github.com/acrefoot/django/branches
use this branch: acrefoot-bulk_create_with_id-1.5.1
on acrefoot-bulk_create_with_id-1.5.1
relevant sha1: ac6d885b811f7e2e34f0db0da217983f7dfd357f

(imported from commit b0dab9dac784d3ff47751e65bf22c2dddc22edf5)
2013-05-24 21:23:57 -04:00
Tim Abbott 5d61e32d25 message_edit: Store rendered content and rendered content version.
(imported from commit 5ddc18a19ff945ed327e4cc03a8183bbfd190c9b)
2013-05-24 21:23:56 -04:00
Tim Abbott 8479b4f0cd [schema] Record and display whether a message was edited.
We also record the historical edits to the message in this JSON format:

 [{"prev_content": "new test message 14", "timestamp": 1369157249},
  {"prev_content": "new test message 13", "timestamp": 1369157118}]

but we don't actually do anything with the information as of yet.

(imported from commit 2d5ca449b87b33ad035ab0e076a22e150c8e7267)
2013-05-24 21:23:55 -04:00
Tim Abbott c98b37550e Record how much time is spent in the markdown parser.
(imported from commit c382f4f88ae253a47e05b3d15c6d21bc0cbb2bb7)
2013-05-22 14:41:57 -04:00
Tim Abbott 5b8dc0d09a Unify our various link processors into a single processor.
There was no benefit to our various link processors all doing
independent scans through the list of messages, and this makes it much
easier to understand the logic of how each link will be handled, and
also makes policies like "don't process links if there are more than 5
of then" easier to implement coherently.

(imported from commit 4affdeab889ba89b99eec905fdf871e78bbc3dd4)
2013-05-22 13:43:20 -04:00
Zev Benjamin 22e2eb3305 Use different mixpanel tokens while deployed vs in development
(imported from commit 4fac466a822d49cb0e1a7592dbd77d8ee019803e)
2013-05-21 17:56:49 -04:00
Zev Benjamin ae9be7298d Wrap render_to_response
(imported from commit d23aa3e5ad4c5243e83df098953ea4b1f7b3c294)
2013-05-21 17:56:49 -04:00
Tim Abbott d467a93877 Add support for updating messages after they've been received.
Currently the interface for editing messages is limited to a
command-line API tool; it's great for testing with e.g.:

./api/examples/edit-message --message=348135 --content="test $(date +%s)" --site=http://localhost:9991 --subject="test"

The next commit will add a user interface for actually doing the editing.

(imported from commit bdd408cec2946f31c2292e44f724f96ed5938791)
2013-05-20 23:40:26 -04:00
Tim Abbott 56949b4788 Create subscription objects in bulk by user_profile.
This, combined with acrefoot's work on sending the notifications in
bulk, resolves trac #1142 -- we do only 10 database queries and the
whole operation completes in about 300ms on my laptop.

(imported from commit 36b5bb836bc6c713903d1ca72e39af87775dc469)
2013-05-20 23:29:54 -04:00
Tim Abbott c325794f3c Send Markdown parser failures to the errors stream.
(imported from commit 8638744ec45d6505fe3a7be87df0a70943f23996)
2013-05-20 23:29:54 -04:00
Luke Faraone 1bb9def157 Only contact embed.ly if we have items that are not cached to fetch.
(imported from commit 8016d1f5dac6a75ced63bec8f0f11d9e4020cccb)
2013-05-14 08:00:37 -07:00
Tim Abbott a4c5c24029 Use the event system to sync onboarding steps across browser tabs.
(imported from commit 29311390133aca8f3a3d79fbe06dbbcabc4fb6ea)
2013-05-14 10:27:40 -04:00
Jessica McKellar 76a57e78ed Enumerate onboarding steps client-side, and give a way to update them.
(imported from commit 0a993976e898cdb20ebb814a19d520572ef8b7e6)
2013-05-14 10:27:39 -04:00
Jessica McKellar 24bb8ad797 onboarding: give new users a list of uncompleted onboarding steps.
(imported from commit 068a6e2112db98965ec5a1c5fc69a9fe285c0333)
2013-05-14 10:27:39 -04:00
Tim Abbott c6f04a2c75 Do memcached accounting on the memcached repopulating commands.
(imported from commit 56b30c04e7aee9c9d8493d872b3b367f2be14262)
2013-05-13 17:11:31 -04:00
Leo Franchi 7f04c8f9b9 Set a Reply-To header in our missed emails, and from noreply@
Otherwise, warn about not replying to this email.

(imported from commit bdcd8f510a8636b25c3c28aaef146a6e916a7d9f)
2013-05-13 11:59:35 -04:00
Leo Franchi 29413867b7 Use just one cache key for all tweet lookups
Since we log to statsd our cache time lookups by cache key, using a unique
tweet id for each lookup was just filling up our cache without being useful.

Also, log database cache lookups in a further namespace to distinguish between
memcached caches

(imported from commit a2a16b777fb7ab8cd066feee7344f9c8a3c107f5)
2013-05-11 15:51:40 -04:00
Zev Benjamin 5508fb5f91 Add restrictions on which streams you can send to
Users can send to any stream except invite-only streams that they
aren't subscribed to.  Bots can send to any stream except invite-only
streams that neither they nor their owner is subscribed to.

(imported from commit 623d34d249d923611ca7ca781b5b55205cd3e548)
2013-05-11 02:38:32 -04:00
Zev Benjamin 73be68fbb9 [schema] Add support for bot users
(imported from commit 634a8211b41fd0040c95b51b96a88d3517fa8cf4)
2013-05-11 02:38:32 -04:00
Tim Abbott 97840da0d2 Fix memcached accounting for bulk set/gets.
After this change, the memcached time consumed by doing
get_old_messages for 200 and 1000 messages respectively now look like
this:

200  63ms (mem: 6ms/3) (db: 4ms/2q) /json/get_old_messages
200 178ms (mem: 67ms/2) (db: 6ms/1q) /json/get_old_messages

which might help explain where the time is going on prod for some of
our slower queries.

(imported from commit b8fe83b175914b6796922a65a1c5537f4e7a9429)
2013-05-10 17:52:45 -04:00
Leo Franchi c28968c848 Only send huddles once per email
(imported from commit 5dc9e209346d14f3c5af1d07e626d771c7d3a95d)
2013-05-09 15:50:05 -04:00
Luke Faraone 3c08781764 Limit the number of URLs we parse at once to 5.
(imported from commit 876c0d0713b4a4d328e4a69e46c984694f5bce1b)
2013-05-09 10:44:08 -04:00
Luke Faraone 2c44ed1096 Log URLs that cause Embedly timeouts.
(imported from commit 84fdca163f6fefae5adc5ea4849d4d707aa7049e)
2013-05-09 10:44:08 -04:00
Luke Faraone f8d443c3c9 Time out embed.ly calls after 2.5 seconds.
(imported from commit 903b800a8444ff5c0b463dba17b2653e1775ae81)
2013-05-09 10:44:08 -04:00
Waseem Daher 47ac589f87 Make inline previews smaller.
(imported from commit 228f6f6f296877810824f98ea8001e47cf955cf1)
2013-05-09 10:44:08 -04:00
Luke Faraone 0513d9760a Batch-process and cache responses from the Embedly API
(imported from commit c427e2bf8f0f32dc632b05f41fa18ab10d0b6d03)
2013-05-09 10:44:08 -04:00
Luke Faraone 9fec3cd3c0 Explicitly skip Twitter links.
(imported from commit 2452dd4d92febbfc2b83ab0e09d7158f4bda76e3)
2013-05-09 10:44:08 -04:00
Luke Faraone fac83ed2b7 [manual] Add support for Embedly Extract
For sites that are supported, we now grab thumbnails for images + video
embed code for videos and use them in lieu of our existing embed code.

We also embed rich non-script content.

Special casing is done so that we don't embed images twice.

Some testcases were modified to avoid triggering Embed.ly

The manual step is to install python-embedly.

(imported from commit d725bab91675c61953116c5ca741055fce49724e)
2013-05-09 10:42:49 -04:00
Luke Faraone 8601c1670f bugdown: Factor out creating a link into its own method
(imported from commit 869cec9927570c4126b78f90aeedc2d5b542d097)
2013-05-09 10:42:19 -04:00
Luke Faraone 598c3a00f2 Comment change: link to a StackOverflow answer directly
(imported from commit a106b02e734956cab88445d159be18a092ae6d46)
2013-05-09 10:41:33 -04:00
Luke Faraone a470ec2e71 Pass the full stack trace in markdown processor errors.
(imported from commit fb157ab44fbf1465d1529ded4af4e04b2c7e9c55)
2013-05-09 10:41:32 -04:00
Tim Abbott 4ab4772758 Only register a Tornado rabbitmq handler if we're using rabbitmq.
(imported from commit 726934bc9acab3b19720f6b5ab1d0736ddd96832)
2013-05-09 10:35:49 -04:00
Leo Franchi 246b4a8459 Fix humbug url
(imported from commit b0fb11acd5f957a71387fe997d292fd6a9d17f39)
2013-05-09 10:35:48 -04:00
Leo Franchi 4173862833 Send notification with missed message to users if they received a PM while offline
This is configurable in the user's settings on Humbug

(imported from commit 80bf6d7a6f0dc3811117548e2225865db8b533d9)
2013-05-09 10:35:48 -04:00
Leo Franchi 06f33a2bde Add code to generate emails for messages that a user missed
(imported from commit 36d3dd9bebbdc9d2af0b0f14acd7f0f6550be4b4)
2013-05-09 10:35:48 -04:00
Leo Franchi 26fd7649f7 Add queue support for draining a queue completely
(imported from commit 50cc52f8b5b74b274024222596c6f2bd27832c89)
2013-05-09 10:35:48 -04:00
Tim Abbott 74148518b4 events: Fix the requesting client type being always internal.
(imported from commit b03bee006547ee811c2f0af66d82dfe6bc4331fc)
2013-05-09 10:35:47 -04:00
Tim Abbott d45527864c bugdown: Include server name in markdown failure emails.
(imported from commit 5b090480a66ca04f7b065215c8c5da698b6c5358)
2013-05-09 10:35:45 -04:00
Leo Franchi 0da2f51ddb Calculate presence information with delta between server timestamp
(imported from commit b4b367ed620878e6d01287cb1aaae0730c7475c8)
2013-05-06 13:52:23 -04:00
Tim Abbott f06fdbb7a8 Fix Zephyr mirroring loop detection with new events API.
(imported from commit 79454bb26851b2f4a61d6cdf04350386671618a5)
2013-05-03 18:20:34 -04:00
Luke Faraone 6bc2d21b87 Make audible notifications a tunable.
This decouples from Chrome notifications, which gives us cross-platform
support in at least modern browsers.

We log this action so its replayable in our message logs.

This implements the model change indicated by the previous schema commit.

(imported from commit b21213cdde54f43670bbb0bf1f607147fc732b38)
2013-05-03 15:08:49 -07:00
Jeff Arnold 105fdc076b Reserve height=100 for images so that collapsing takes them into account
Addresses #1204

(imported from commit 9a1f4b13ab14c4b8fc4eab50178b9c28f477fcd7)
2013-05-02 18:53:34 -04:00
Leo Franchi 5ef7c4e6db Add a management command for active user stats
(imported from commit a4227858b422c48e272700880e0c21889c7ce566)
2013-05-01 11:17:18 -04:00
Tim Abbott e3bb1bc8ec bugdown: Fix tweet ID extraction from twitter urls.
(imported from commit 88b9882527a5317bf30bcc5f0d1255e819ea149c)
2013-04-30 10:43:17 -04:00
Tim Abbott 7c001822f2 Use bulk requests for updating memcached in get_old_messages.
Otherwise we end up doing 1000 requests to memcached, which can be
quite expensive.

(imported from commit be247f63b5fb88c6f4a45326261b66ea67fe1028)
2013-04-25 14:43:37 -04:00
Zev Benjamin 3e1ec5d7c9 Increase size of initial message cache fetch and exclude tabbott/extra's messages
(imported from commit 59544aa3adfb05f50ca69e56f37f57944dfa0b81)
2013-04-25 13:33:51 -04:00
Zev Benjamin a1634b12d3 Increase efficiency of initial message cache query
In repeated trials, the initial data fetch used to take about 1100ms.
In practice, it was often taking >2000ms, probably due to caching
effects.  This commit cuts the time down to about 300ms in repeated
trials.

Note that the semantics are changed slightly in that we may no longer
get exactly 25000 messages.  However, holes in the message_id
sequence are currently very rare or non-existent so this shouldn't be
a problem and we don't care about the exact number of messages
anyway.

I believe the problem was that the query planner was unable to
effectively use the LIMIT clause to figure out that only a small
subset of zephyr_message was going to be needed.  Thus, it planned
for operating on the entire table and decided it could not use a more
efficient plan because work_mem, although large, would not be large
enough to execute the query over all of zephyr_message.

The original query was:

SELECT "zephyr_message"."id", "zephyr_message"."sender_id", "zephyr_message"."recipient_id", "zephyr_message"."subject", "zephyr_message"."content", "zephyr_message"."rendered_content", "zephyr_message"."rendered_content_version", "zephyr_message"."pub_date", "zephyr_message"."sending_client_id", "zephyr_userprofile"."id", "zephyr_userprofile"."password", "zephyr_userprofile"."last_login", "zephyr_userprofile"."email", "zephyr_userprofile"."is_staff", "zephyr_userprofile"."is_active", "zephyr_userprofile"."date_joined", "zephyr_userprofile"."full_name", "zephyr_userprofile"."short_name", "zephyr_userprofile"."pointer", "zephyr_userprofile"."last_pointer_updater", "zephyr_userprofile"."realm_id", "zephyr_userprofile"."api_key", "zephyr_userprofile"."enable_desktop_notifications", "zephyr_userprofile"."enter_sends", "zephyr_userprofile"."tutorial_status", "zephyr_realm"."id", "zephyr_realm"."domain", "zephyr_realm"."restricted_to_domain", "zephyr_recipient"."id", "zephyr_recipient"."type_id", "zephyr_recipient"."type", "zephyr_client"."id", "zephyr_client"."name" FROM "zephyr_message" INNER JOIN "zephyr_userprofile" ON ( "zephyr_message"."sender_id" = "zephyr_userprofile"."id" ) INNER JOIN "zephyr_realm" ON ( "zephyr_userprofile"."realm_id" = "zephyr_realm"."id" ) INNER JOIN "zephyr_recipient" ON ( "zephyr_message"."recipient_id" = "zephyr_recipient"."id" ) INNER JOIN "zephyr_client" ON ( "zephyr_message"."sending_client_id" = "zephyr_client"."id" ) ORDER BY "zephyr_message"."id" DESC LIMIT 25000;

with query plan:
 Limit  (cost=0.00..27120.95 rows=25000 width=362) (actual time=0.051..1121.282 rows=25000 loops=1)
   ->  Nested Loop  (cost=0.00..5330872.99 rows=4913981 width=362) (actual time=0.048..1081.014 rows=25000 loops=1)
         ->  Nested Loop  (cost=0.00..3932643.31 rows=4913981 width=344) (actual time=0.042..926.398 rows=25000 loops=1)
               ->  Nested Loop  (cost=0.00..2550275.29 rows=4913981 width=334) (actual time=0.035..752.524 rows=25000 loops=1)
                     Join Filter: (zephyr_message.sending_client_id = zephyr_client.id)
                     ->  Nested Loop  (cost=0.00..1739467.29 rows=4913981 width=320) (actual time=0.024..217.348 rows=25000 loops=1)
                           ->  Index Scan Backward using zephyr_message_pkey on zephyr_message  (cost=0.00..362510.09 rows=4913981 width=156) (actual time=0.014..42.097 rows=25000 loops=1)
                           ->  Index Scan using zephyr_userprofile_pkey on zephyr_userprofile  (cost=0.00..0.27 rows=1 width=164) (actual time=0.003..0.004 rows=1 loops=25000)
                                 Index Cond: (id = zephyr_message.sender_id)
                     ->  Materialize  (cost=0.00..1.17 rows=11 width=14) (actual time=0.001..0.010 rows=11 loops=25000)
                           ->  Seq Scan on zephyr_client  (cost=0.00..1.11 rows=11 width=14) (actual time=0.002..0.010 rows=11 loops=1)
               ->  Index Scan using zephyr_recipient_pkey on zephyr_recipient  (cost=0.00..0.27 rows=1 width=10) (actual time=0.002..0.003 rows=1 loops=25000)
                     Index Cond: (id = zephyr_message.recipient_id)
         ->  Index Scan using zephyr_realm_pkey on zephyr_realm  (cost=0.00..0.27 rows=1 width=18) (actual time=0.002..0.003 rows=1 loops=25000)
               Index Cond: (id = zephyr_userprofile.realm_id)
 Total runtime: 1141.408 ms

In the new code, we do two queries:

SELECT "zephyr_message"."id" FROM "zephyr_message" ORDER BY "zephyr_message"."id" DESC LIMIT 1

followed by:

SELECT "zephyr_message"."id", "zephyr_message"."sender_id", "zephyr_message"."recipient_id", "zephyr_message"."subject", "zephyr_message"."content", "zephyr_message"."rendered_content", "zephyr_message"."rendered_content_version", "zephyr_message"."pub_date", "zephyr_message"."sending_client_id", "zephyr_userprofile"."id", "zephyr_userprofile"."password", "zephyr_userprofile"."last_login", "zephyr_userprofile"."email", "zephyr_userprofile"."is_staff", "zephyr_userprofile"."is_active", "zephyr_userprofile"."date_joined", "zephyr_userprofile"."full_name", "zephyr_userprofile"."short_name", "zephyr_userprofile"."pointer", "zephyr_userprofile"."last_pointer_updater", "zephyr_userprofile"."realm_id", "zephyr_userprofile"."api_key", "zephyr_userprofile"."enable_desktop_notifications", "zephyr_userprofile"."enter_sends", "zephyr_userprofile"."tutorial_status", "zephyr_realm"."id", "zephyr_realm"."domain", "zephyr_realm"."restricted_to_domain", "zephyr_recipient"."id", "zephyr_recipient"."type_id", "zephyr_recipient"."type", "zephyr_client"."id", "zephyr_client"."name" FROM "zephyr_message" INNER JOIN "zephyr_userprofile" ON ( "zephyr_message"."sender_id" = "zephyr_userprofile"."id" ) INNER JOIN "zephyr_realm" ON ( "zephyr_userprofile"."realm_id" = "zephyr_realm"."id" ) INNER JOIN "zephyr_recipient" ON ( "zephyr_message"."recipient_id" = "zephyr_recipient"."id" ) INNER JOIN "zephyr_client" ON ( "zephyr_message"."sending_client_id" = "zephyr_client"."id" ) WHERE "zephyr_message"."id" > 4941883

with the message id filled in as the result of the first query.  The
new query differs from the original only in that its ORDER BY and
LIMIT clauses are replaced by a WHERE clause.  The second query has
query plan:

 Hash Join  (cost=709.30..28048.18 rows=20544 width=365) (actual time=41.678..279.261 rows=25041 loops=1)
   Hash Cond: (zephyr_message.recipient_id = zephyr_recipient.id)
   ->  Hash Join  (cost=102.98..27056.66 rows=20544 width=355) (actual time=3.686..190.730 rows=25041 loops=1)
         Hash Cond: (zephyr_message.sending_client_id = zephyr_client.id)
         ->  Hash Join  (cost=101.73..26772.94 rows=20544 width=341) (actual time=3.649..143.695 rows=25041 loops=1)
               Hash Cond: (zephyr_userprofile.realm_id = zephyr_realm.id)
               ->  Hash Join  (cost=99.99..26488.71 rows=20544 width=323) (actual time=3.578..96.746 rows=25041 loops=1)
                     Hash Cond: (zephyr_message.sender_id = zephyr_userprofile.id)
                     ->  Index Scan using zephyr_message_pkey on zephyr_message  (cost=0.00..26106.24 rows=20544 width=159) (actual time=0.017..41.980 rows=25041 loops=1)
                           Index Cond: (id > 4941883)
                     ->  Hash  (cost=83.33..83.33 rows=1333 width=164) (actual time=3.548..3.548 rows=1333 loops=1)
                           Buckets: 1024  Batches: 1  Memory Usage: 275kB
                           ->  Seq Scan on zephyr_userprofile  (cost=0.00..83.33 rows=1333 width=164) (actual time=0.006..1.646 rows=1333 loops=1)
               ->  Hash  (cost=1.33..1.33 rows=33 width=18) (actual time=0.064..0.064 rows=33 loops=1)
                     Buckets: 1024  Batches: 1  Memory Usage: 2kB
                     ->  Seq Scan on zephyr_realm  (cost=0.00..1.33 rows=33 width=18) (actual time=0.003..0.033 rows=33 loops=1)
         ->  Hash  (cost=1.11..1.11 rows=11 width=14) (actual time=0.027..0.027 rows=11 loops=1)
               Buckets: 1024  Batches: 1  Memory Usage: 1kB
               ->  Seq Scan on zephyr_client  (cost=0.00..1.11 rows=11 width=14) (actual time=0.003..0.013 rows=11 loops=1)
   ->  Hash  (cost=335.03..335.03 rows=21703 width=10) (actual time=37.974..37.974 rows=21761 loops=1)
         Buckets: 4096  Batches: 1  Memory Usage: 893kB
         ->  Seq Scan on zephyr_recipient  (cost=0.00..335.03 rows=21703 width=10) (actual time=0.004..18.443 rows=21761 loops=1)
 Total runtime: 299.300 ms

(imported from commit b2a70cccc47be7970df407c6be00eccd2e8be82a)
2013-04-25 13:25:15 -04:00
Tim Abbott 102988e430 Refill the Session cache after restarting the server.
The fact that we were dumping this cache and not refilling it seems to
be one of the causes of Tornado restarts being a lot slower on prod
than on local systems.

(imported from commit a32a759f4dfb591706ede1cce2d38f5c3704193c)
2013-04-24 10:44:56 -04:00
Tim Abbott 9b8f0fab0f Retrieve message objects from memcached in a bulk request.
On my laptop, this saves about 80 milliseconds per 1000 messages
requested via get_old_messages queries.  Since we only have one
memcached process and it does not run with special priority, this
might have significant impact on load during server restarts.

(imported from commit 06ad13f32f4a6d87a0664c96297ef9843f410ac5)
2013-04-24 10:44:56 -04:00
Tim Abbott 66b3c1fbff Log time spent querying memcached in logs when larger than 5ms.
(imported from commit a4de15026d24526a446b724500d1194dce824d1a)
2013-04-24 10:44:56 -04:00
Tim Abbott 5e22778843 Use a function for stopping/restarting time logging for longpolling.
(imported from commit 11b772deaa126fcc7e7605d467022b22d9e98cb0)
2013-04-24 10:44:56 -04:00
Waseem Daher 20233cfc96 Time out on Twitter rendering if it takes too long.
Timing out within the Twitter portion of the render causes the message
to still go through (without a preview). If we don't timeout here, it
causes the entire Markdown render to timeout, which rejects the
message in its entirety -- a far worse outcome.

(imported from commit f510a56f48afa46da8ec6277496fa03374cdb042)
2013-04-23 12:56:34 -04:00
Luke Faraone 71a91197fa Enable absolute imports.
See PEP 328[1] for details. This feature was introduced in Python 2.5 and
will become mandatory in Python 3.

[1]: http://www.python.org/dev/peps/pep-0328

(imported from commit 7444eeba8a08d5f91b94c7921848f2274979bd76)
2013-04-23 09:51:17 -07:00
Leo Franchi 7b0423efc1 Use incr instead of gauge when sending events to drawAsInfinite to statsd
(imported from commit 08a4b6920c7a4a8f472f147ddce7c04710fe5c0a)
2013-04-19 09:56:41 -04:00
Leo Franchi 652b821d64 Add a bunch of statsd logging
(imported from commit 8c17a76fed08c34abab3cc45d76a0fb30774d73a)
2013-04-18 18:05:52 -04:00
Leo Franchi 46415d4984 Add statsd helpers and wrappers
(imported from commit 9d5b805ae416a65ac49dda8e8e11d9831308116c)
2013-04-18 18:05:52 -04:00
Tim Abbott 5afe06e8cb Decrease idle event queue timeout back to 10 minutes.
(imported from commit 1ca1c99c013f3e7f7e70e1fd9c5386b0d5a27b98)
2013-04-18 16:58:31 -04:00
Leo Franchi aa75f51d5e Catch IncompatibleProtoclErrors as well, since our failure to connect might happen during the initial handshake phase
(imported from commit 55115f19a5a101676e3ce1ca2a7b9cd2a2d5b028)
2013-04-18 15:46:43 -04:00
Leo Franchi fb2b3ae21a Handle multiple preregistration user objects when choosing streams
(imported from commit 52faa0256a719bed8a8ccc120f8177cce20450e2)
2013-04-17 15:48:30 -04:00
Leo Franchi 0aa20cb594 Rework saved consumer logic in TornadoQueue to always reconnect consumers
(imported from commit 0627d769349077c1e795db9215b17f538e9ec75c)
2013-04-17 12:11:28 -04:00