CREATE OR REPLACE FUNCTION microsharding_notice_locks_(
  prefix text,
  prev_shown_at timestamptz = NULL
) RETURNS timestamptz
LANGUAGE plpgsql
SET search_path FROM CURRENT
AS $$
DECLARE
  backend_pid bigint := pg_backend_pid();
  old_client_min_messages text;
  msg text;
BEGIN
  IF prev_shown_at IS NULL OR clock_timestamp() - prev_shown_at > '2 seconds'::interval THEN
    prev_shown_at := clock_timestamp();
    msg := (
      SELECT string_agg(substring(locktype FOR 3) || ':' || mode || '=' || count, ' ')
      FROM (
        SELECT locktype, mode, count(1) AS count
        FROM pg_locks
        WHERE pid = backend_pid
        GROUP BY locktype, mode
        ORDER BY count DESC
        LIMIT 5
      ) t
    );
    old_client_min_messages := current_setting('client_min_messages', true);
    PERFORM set_config('client_min_messages', 'NOTICE', true);
    RAISE NOTICE '%. Locks held: %', prefix, msg;
    PERFORM set_config('client_min_messages', old_client_min_messages, true);
  END IF;
  RETURN prev_shown_at;
END;
$$;

COMMENT ON FUNCTION microsharding_notice_locks_(text, timestamptz)
  IS 'Shows locks statistics periodically as NOTICEs.';
