#!/usr/bin/env python
"""
Flush control for ep-engine.

Copyright (c) 2010  Dustin Sallings <dustin@spy.net>
"""
import sys
import time

import clitool

def auth(mc, username, password):
    if username:
        mc.sasl_auth_plain(username, password)

def stop(mc, username=None, password=""):
    auth(mc, username, password)
    mc.stop_persistence()
    stopped = False
    while not stopped:
        time.sleep(0.5)
        try:
            stats = mc.stats()
            success = True
        except:
            if success:
                import mc_bin_client
                mc = mc_bin_client.MemcachedClient(mc.host, mc.port)
                raise
            else:
                raise
        success = False
        if stats['ep_flusher_state'] == 'paused':
            stopped = True

def start(mc, username=None, password=""):
    auth(mc, username, password)
    mc.start_persistence()

def set_param(mc, key, val, username=None, password=""):
    if key == 'tap_throttle_queue_cap' and val == 'infinite':
        val = '-1'
    auth(mc, username, password)
    mc.set_flush_param(key, val)

def evict(mc, key, username=None, password=""):
    auth(mc, username, password)
    mc.evict_key(key)

def drain(mc, username=None, password=""):
    auth(mc, username, password)
    while True:
        s = mc.stats()
        if s['ep_queue_size'] == "0" and \
           s['ep_flusher_todo'] == "0":
           print("done")
           return
        time.sleep(2)
        sys.stdout.write('.')
        sys.stdout.flush()

if __name__ == '__main__':

    c = clitool.CliTool("""
All commands allow an optional username and password as the last
two parameters.

Persistence:
    stop           - stop persistence
    start          - start persistence
    drain          - wait until queues are drained

Available params for "set":
    bg_fetch_delay         - Delay before executing a bg fetch (test feature)
    chk_max_items          - Maximum items before creating a new checkpoint
    chk_period             - Duration before creating a new checkpoint
    exp_pager_stime        - Expiry Pager Sleeptime
    inconsistent_slave_chk - Enables active to active replication
    queue_age_cap          - Maximum queue age before flushing data
    max_checkpoints        - Maximum number of checkpoints
    max_size               - Max memory used by the server
    max_txn_size           - Maximum number of items in a flusher transaction
    mem_high_wat           - High water mark
    mem_low_wat            - Low water mark
    min_data_age           - Minimum data age before flushing data
    sync_cmd_timeout       - The timeout for the sync command
    tap_throttle_queue_cap - Destination disk write queue cap for tap backoff
                             ('infinite' means no cap)
    tap_throttle_threshold - Destination memory threshold for tap backoff
    keep_closed_chks       - Keep all closed checkpoints in memory
    flushall_enabled       - Enable flush operation
    """)

    c.addCommand('stop', stop, 'stop [username password]')
    c.addCommand('start', start, 'start [username password]')
    c.addCommand('set', set_param, 'set param value [username password]')
    c.addCommand('evict', evict, 'evict key [username password]')
    c.addCommand('drain', drain, 'drain [username password]')

    c.execute()
