Skip to content

Instantly share code, notes, and snippets.

@yashap
yashap / join_perf_example.md
Last active September 13, 2023 04:10
Example of how sometimes a normalized schema + joins kills performance vs. denormalizing

Normalized/join vs. denormalized/no-join performance example

An example of how sometimes you have to denormalize your schema, so that you can build compound indexes, to get acceptable performance. In some cases a normalized schema with join(s) just won't be fast enough.

Note: I think in almost all cases you should start with a normalized schema and use joins. But when you hit cases like the above, it's fine to denormalize just for these specific cases - often you'll just have one or a few such cases in your entire app, where the combination of data size/shape/queries means you cannot have efficient queries without denormalizing.

Notes on CSRF

What is CSRF?

CSRF attacks are basically session hijacking. Say I'm logged in to foo.com, which has an endpoint like POST http://foo.com/api/password { "password": $newPassword }. Obviously this endpoint will fail if I'm not logged in, but that's not enough protection on its own, assuming the proof of my login is stored as a session cookie. An attacker could set up a site like attacker.com, and on load of the attacker site, it automatically makes a request like POST http://foo.com/api/password { "password": "uHackedNow!" }. If I visit http://attacker.com while logged in to foo.com, and foo.com doesn't have CSRF protection built in, I'm screwed, because the browser will automatically send along my foo.com cookies (including the session cookie) on requests to foo.com, and thus the attacker is able to change my password.

Preventing CSRF Attacks

The below is a quick summary of notes from:

#!/usr/bin/env scala
// This is my solution to http://fivethirtyeight.com/features/who-keeps-the-money-you-found-on-the-floor/
// To run it, just check out the script, make it executable (`chmod +x riddler_solution`), then execute it (`./riddler_solution`)
// You will need the Scala programming language first (if you're on a Mac with Homebrew installed, just `brew install scala`)
import scala.util.Random
import scala.collection.mutable.ListBuffer
class Statistician(val id: Int, rng: Random, winnerLog: ListBuffer[Int], left: => Statistician, right: => Statistician) {
@yashap
yashap / futureRetry.scala
Created September 25, 2015 18:49
Retry a future on failure, with a delay, up to n times
import scala.concurrent.{Promise, Future, ExecutionContext}
import scala.concurrent.duration.FiniteDuration
import java.util.{TimerTask, Timer}
// Inspired by https://gist.github.com/viktorklang/9414163, but modified to not depend on Akka, works with just Scala's standard library
def retry[T](block: => T, delay: FiniteDuration, retries: Int)(implicit ec: ExecutionContext): Future[T] =
Future(block).recoverWith { case _ if retries > 0 =>
after(delay)(retry(block, delay, retries - 1))
}