Procfile dependencies

Tagged overmind, foreman, dependencies, sleep, procfile  Languages bash

You can use the sleep command as a way of specifying dependencies in a Procfile even if dependencies are not explicitly supported.

For example:

redis:        redis-server
sidekiq:      sleep 5; bundle exec sidekiq
rails:        sleep 5; bundle exec rails
proxy:        sleep 10; haproxy -c haproxy.cfg

SSH jump host

Tagged jump, host, ssh  Languages bash
# Connect to server-b by going through server-a (you => server-a => server-b):
$ ssh -t <user>@<server-a> ssh <server-b>

How to solve "CreateContainerConfigError" in Kubernetes

Tagged createcontainerconfigerror, kubectl, k8s  Languages bash

To solve CreateContainerConfigError you can try this command:

$ kubectl describe pod xxx-86cbd7555b-2zrs2
...
...
  Warning  Failed     75s (x8 over 2m50s)  kubelet, k8s-node1  Error: couldn't find key XXX in ConfigMap default/xxx
...

Bash aliases / functions for kubectl

Tagged kubectl, k8s, aliases  Languages bash

Put the following functions in, for example, ~/.bash_aliases:

function kshell() { kubectl exec -it "$1" -- /bin/bash ;}
function kpods() { kubectl get po -n default -o wide ;}
function klogs() { kubectl logs --tail=100 -f "$1" ;}
function krestart() { kubectl rollout restart "deploy/$1" ;}
function kdesc() { kubectl describe pod $1;}
function ksecret() { kubectl get secret $1 -o jsonpath="{.data.$2}" | base64 --decode ;}

Your RSI and symptoms of cognitive dissonance will disappear in about 6 months.

Debugging Webpacker (Rails)

Tagged rails, webpacker  Languages bash

If Webpacker fails to compile your Javascripts without including any output:

[Webpacker] Compiling…
[Webpacker] Compilation failed:

Try running webpacker from the command line:

$ ./bin/webpack --progress --profile

How to find all tables referring to another table in Postgres

Tagged column, postgresql  Languages sql

This example lists all tables that contain a column named ‘organization_id’:

SELECT c.relname AS table,
       a.attname AS column,
       n.nspname AS schema
FROM   pg_class AS c
       INNER JOIN pg_attribute AS a
               ON a.attrelid = c.oid
       JOIN pg_namespace n
         ON n.oid = c.relnamespace
WHERE  a.attname = 'organization_id'
       AND c.relkind = 'r'
       AND c.relname NOT LIKE 'pg_%'
ORDER  BY c.relname,
          a.attname  

The Scientific Method

Tagged growth, hypothesis, marketing, method, research, scientific, testing  Languages 

“The Scientific Method” from https://www.reforge.com/blog/run-growth-team-like-a-scientist

Inputs

  1. Question: What do I want to understand?
  2. Hypothesis: What is my proposed explanation to the question?
  3. Experiment: Design an experiment to test the hypothesis.

Outputs

  1. Observation: Observe the experiment and record results.
  2. Analysis: Interpret the results.

Notes

the qualitative inputs - question, hypothesis, and experiment design - are the most important steps of the process. If you get these steps right, you increase your chances of running successful experiments that produce valid results and actionable insights.

So, what separates the good growth teams (and research labs) from the great ones?

It’s the quality of the questions they ask, the hypotheses they come up with, and how they construct their experiments.

A one-day or one-week in vitro test using a landing page builder to mockup a subscription pricing page, driving traffic to it via ads, and measuring conversion rates against current pricing may have quickly revealed that a subscription pricing model wasn’t appealing to their customer base.

the point is to use an in vitro test to get validation that an in vivo test is worth the additional resources. Tools like Unbounce, Optimizely, and paid advertising make these kinds of in vitro tests easy and fast.

One of my favorite mentors, Anantha Katragadda, told me when I was starting out in growth that if I couldn’t think of a way to fake a product experience in order to get validating data, I simply wasn’t trying hard enough.

To publish a paper, every result must disprove the null hypothesis. This means that you prove, with statistical significance, that the result you are seeing is not due to random chance or biased observation

Temporal tables in PostgreSQL

Tagged postgres, slowly changing, temporal  Languages sql

To implement temporal tables in PostgreSQL, see Magnus Hagander’s “A TARDIS for your ORM” presentation: https://www.hagander.net/talks/tardis_orm.pdf

Temporal tables allow you to travel back in time and see your data as it was right after the big bang, or right before your data arrived at the event horizon.

The following code is from https://gist.github.com/iperdomo/74890685f3c76b0fc139 and implements the gist of time travel:

-- psql -U postgres -h localhost -f /path/to/tardis.sql

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

CREATE DATABASE tardis WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';

\connect tardis

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;


CREATE SCHEMA history;

CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;

CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public;

CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;

SET search_path = history, pg_catalog;

CREATE FUNCTION log_change() RETURNS trigger
    LANGUAGE plpgsql
    AS $_$
    DECLARE
      c refcursor;
      tt tstzrange;
    BEGIN
        IF TG_OP = 'INSERT' THEN
            EXECUTE 'INSERT INTO history.' || TG_TABLE_NAME ||
              ' SELECT $1.*, tstzrange(now(), $$infinity$$, $$[)$$)' USING NEW;
            RETURN NEW;
        ELSIF TG_OP = 'UPDATE' THEN
            OPEN c FOR EXECUTE 'SELECT _validrange FROM history.' || TG_TABLE_NAME ||
              ' WHERE id = $1 ORDER BY _validrange DESC LIMIT 1 FOR UPDATE'
              USING NEW.id;
            FETCH FROM c INTO tt;

            IF isempty(tstzrange(lower(tt), now(), $$[)$$)) THEN

                -- What edge case are we missing by commenting the following lines of code?
        -- How can we get the lastxid value?

        --IF NOT lastxid = txid_current() THEN
        --    RAISE EXCEPTION 'UPDATE would have empty validity: %d!', OLD;
        --END IF;

        EXECUTE 'DELETE FROM history.' || TG_TABLE_NAME ||
          ' WHERE CURRENT OF ' || quote_ident(c::text);
            ELSE
                EXECUTE 'UPDATE history.' || TG_TABLE_NAME || ' SET _validrange = tstzrange($1, now(), $$[)$$)' ||
                  ' WHERE CURRENT OF ' || quote_ident(c::text) USING lower(tt);
            END IF;

            EXECUTE 'INSERT INTO history.' || TG_TABLE_NAME ||
              ' SELECT $1.*, tstzrange(now(), $$infinity$$, $$[)$$)' USING NEW;

            RETURN NEW;
        ELSIF TG_OP = 'DELETE' THEN

          OPEN c FOR EXECUTE 'SELECT _validrange FROM history.' || TG_TABLE_NAME ||
            ' WHERE id = $1 ORDER BY _validrange DESC LIMIT 1 FOR UPDATE' USING OLD.id;

          FETCH FROM c into tt;

          IF isempty(tstzrange(lower(tt), now(), $$[)$$)) THEN
            EXECUTE 'DELETE FROM history.' || TG_TABLE_NAME ||
              ' WHERE CURRENT OF ' || quote_ident(c::text);
            RETURN OLD;
          END IF;

          EXECUTE 'UPDATE history.' || TG_TABLE_NAME ||
            ' SET _validrange = tstzrange($1, now(), $$[)$$) WHERE CURRENT OF ' ||
            quote_ident(c::text) USING lower(tt);

          RETURN OLD;
        END IF;
        RETURN NULL;
    END;
$_$;


CREATE TABLE table1 (
    id text NOT NULL,
    name text NOT NULL,
    _validrange tstzrange
);

ALTER TABLE ONLY table1
    ADD CONSTRAINT table1_exclusion EXCLUDE
    USING gist (id WITH =, _validrange WITH &&);


SET search_path = public, pg_catalog;

-- We're using text instead of uuid because btree_gist don't support
-- uuid data type yet and we want to use it for the EXCLUDE constraint
-- See: https://commitfest.postgresql.org/7/332/

CREATE TABLE table1 (
    id text PRIMARY KEY DEFAULT (uuid_generate_v4())::text NOT NULL,
    name text NOT NULL
);

CREATE TRIGGER table1_history BEFORE
  INSERT OR DELETE OR UPDATE ON table1
  FOR EACH ROW EXECUTE PROCEDURE history.log_change();


-- Data

BEGIN;
INSERT INTO table1 (name) VALUES ('name 1');
INSERT INTO table1 (name) VALUES ('name 2');
COMMIT;

BEGIN;
UPDATE table1 SET name = 'name 1.1' WHERE name = 'name 1';
COMMIT;

BEGIN;
-- Since this is a transaction, the first UPDATE is not recorded
-- in the history.table1 (as expected)
UPDATE table1 SET name = 'name 1.2' WHERE name = 'name 1.1';
UPDATE table1 SET name = 'name 1.3' WHERE name = 'name 1.2';
COMMIT;

SELECT * FROM public.table1 WHERE name = 'name 1.3';
SELECT * FROM history.table1 ORDER BY _validrange DESC;

My Mac won't go to sleep

Tagged mac, pmset, sleep  Languages bash

If your Mac won’t go to sleep, try this:

pmset -g assertions

Check the output for details on which processes and voodo magic is keeping your iMac up all night:

Listed by owning process:
   pid 4627(cloudd)...
Idle sleep preventers: IODisplayWrangler

Things you can try:

  • Resetting the printing system (CTRL+click in the left pane of the Printers and scanners settings)
  • Unplugging external devices (USB, bluetooth, etc)
  • Voodoo

References:

https://discussions.apple.com/thread/7256162

https://www.reddit.com/r/applehelp/comments/43ks7u/macbook_wont_go_to_sleep_hidd_preventing_sleep/

https://apple.stackexchange.com/questions/307151/significance-of-iodisplaywrangler-in-power-management-assertions