Skip to content

Use Hooks

Junyi, Lu edited this page Feb 3, 2017 · 7 revisions

Use Hooks

When hook is useful

You may want to interact with OSC when it is running. Hook is a good fit for following use cases:

  • Triggers a shell script at some point during schema change
  • Get more insights about the running OSC
  • Execute a piece of Python code or make a remote thrift call to interactive with your internal environment

How to write a hook

There're some example hooks already implemented under osc/lib/hook.py. Basically all hooks should derive from HookBase and implement the _execute function. The simplest possible hook is NoopHook, it's basically a runnable hook but does nothing.

class MyNewHook(HookBase):
    def _execute(self, payload):
        # add more stuff here

Start with copying the code snippet above into osc/lib/hook.py. Then put whatever python code you want into _execute function. For example use os.system to execute a shell script, open a file and write something into it, or make a thrift call. Anything you can think of, and can be implemented using python can be put in this function.

Pick when to run this hook

Now we have the hook ready, let's put it somewhere to run. First let's pick a place to hook your class into for which we call it hook point. A legit hook point is any function name in osc/lib/payload/copy.py wrapped with @wrap_hook decorate, and with prefix before_ or after_. Below is a non-exhaustive list of currently supported hook points:

  • before_run_ddl/after_run_ddl
  • before_load_data/after_load_data
  • before_swap_tables/after_swap_tables
  • ...

If you would like to trigger your hook somewhere else during the schema change, just add this decorate @wrap_hook before the definition of the function.

Config hook map to make it work

Now we need to config the hook to run at particular hook point. Modify the osc_cli script under the root directory, and add hook config right before cmd.op() as below:

if args.command == 'copy':
    hook_map = defaultdict(lambda: hook.NoopHook())
    # uncomment following line if you want to add a hook config
    hook_map['after_init_connection'] = hook.MyNewHook()
    cmd.args.hook_map = hook_map

# Execute main logic
cmd.op()

Change after_init_connection to whatever hook point you want, and MyNewHook to the hook class you've implemented. Then run osc_cli, you will see relevant line about hook being triggered in the log output.