Basic module-script for spawning `marketstore`, needs correct bind mount usage
							parent
							
								
									fea645423e
								
							
						
					
					
						commit
						c3509e7f93
					
				| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
# piker: trading gear for hackers
 | 
			
		||||
# Copyright (C) 2018-present  Tyler Goodlet (in stewardship of piker0)
 | 
			
		||||
 | 
			
		||||
# This program is free software: you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
# the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
# This program is distributed in the hope that it will be useful,
 | 
			
		||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
# GNU Affero General Public License for more details.
 | 
			
		||||
 | 
			
		||||
# You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
Supervisor for docker with included specific-image service helpers.
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
from typing import Optional
 | 
			
		||||
from contextlib import contextmanager as cm
 | 
			
		||||
# import time
 | 
			
		||||
 | 
			
		||||
import trio
 | 
			
		||||
import tractor
 | 
			
		||||
import docker
 | 
			
		||||
import json
 | 
			
		||||
# from docker.containers import Container
 | 
			
		||||
from requests import ConnectionError
 | 
			
		||||
 | 
			
		||||
from ..log import get_logger, get_console_log
 | 
			
		||||
 | 
			
		||||
log = get_logger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_config = '''
 | 
			
		||||
# mount this config using:
 | 
			
		||||
# sudo docker run --mount type=bind,source="$HOME/.config/piker/",target="/etc" -i -p 5993:5993 alpacamarkets/marketstore:latest
 | 
			
		||||
root_directory: data
 | 
			
		||||
listen_port: 5993
 | 
			
		||||
grpc_listen_port: 5995
 | 
			
		||||
log_level: info
 | 
			
		||||
queryable: true
 | 
			
		||||
stop_grace_period: 0
 | 
			
		||||
wal_rotate_interval: 5
 | 
			
		||||
stale_threshold: 5
 | 
			
		||||
enable_add: true
 | 
			
		||||
enable_remove: false
 | 
			
		||||
 | 
			
		||||
triggers:
 | 
			
		||||
  - module: ondiskagg.so
 | 
			
		||||
    on: "*/1Sec/OHLCV"
 | 
			
		||||
    config:
 | 
			
		||||
        # filter: "nasdaq"
 | 
			
		||||
        destinations:
 | 
			
		||||
            - 1Min
 | 
			
		||||
            - 5Min
 | 
			
		||||
            - 15Min
 | 
			
		||||
            - 1H
 | 
			
		||||
            - 1D
 | 
			
		||||
 | 
			
		||||
  - module: stream.so
 | 
			
		||||
    on: '*/*/*'
 | 
			
		||||
    # config:
 | 
			
		||||
    #     filter: "nasdaq"
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@cm
 | 
			
		||||
def open_docker(
 | 
			
		||||
    url: Optional[str] = None,
 | 
			
		||||
    **kwargs,
 | 
			
		||||
 | 
			
		||||
) -> docker.DockerClient:
 | 
			
		||||
 | 
			
		||||
    # yield docker.Client(
 | 
			
		||||
    #     base_url=url,
 | 
			
		||||
    #     **kwargs
 | 
			
		||||
    # ) if url else
 | 
			
		||||
    yield docker.from_env(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@tractor.context
 | 
			
		||||
async def open_marketstore_container(
 | 
			
		||||
    ctx: tractor.Context,
 | 
			
		||||
    **kwargs,
 | 
			
		||||
 | 
			
		||||
) -> None:
 | 
			
		||||
    log = get_console_log('info', name=__name__)
 | 
			
		||||
    # this cli should "just work"
 | 
			
		||||
    # sudo docker run --mount
 | 
			
		||||
    # type=bind,source="$HOME/.config/piker/",target="/etc" -i -p
 | 
			
		||||
    # 5993:5993 alpacamarkets/marketstore:latest
 | 
			
		||||
    client = docker.from_env(**kwargs)
 | 
			
		||||
 | 
			
		||||
    # with open_docker() as client:
 | 
			
		||||
    ctnr = client.containers.run(
 | 
			
		||||
        'alpacamarkets/marketstore:latest',
 | 
			
		||||
        [
 | 
			
		||||
            '--mount',
 | 
			
		||||
            'type=bind,source="$HOME/.config/piker/",target="/etc"',
 | 
			
		||||
            '-i',
 | 
			
		||||
            '-p 5993:5993',
 | 
			
		||||
        ],
 | 
			
		||||
        detach=True,
 | 
			
		||||
    )
 | 
			
		||||
    started: bool = False
 | 
			
		||||
    logs = ctnr.logs(stream=True)
 | 
			
		||||
 | 
			
		||||
    with trio.move_on_after(0.5):
 | 
			
		||||
        for entry in logs:
 | 
			
		||||
            entry = entry.decode()
 | 
			
		||||
            try:
 | 
			
		||||
                record = json.loads(entry.strip())
 | 
			
		||||
            except json.JSONDecodeError:
 | 
			
		||||
                if 'Error' in entry:
 | 
			
		||||
                    raise RuntimeError(entry)
 | 
			
		||||
                # await tractor.breakpoint()
 | 
			
		||||
            msg = record['msg']
 | 
			
		||||
 | 
			
		||||
            if "launching tcp listener for all services..." in msg:
 | 
			
		||||
                started = True
 | 
			
		||||
                break
 | 
			
		||||
 | 
			
		||||
            await trio.sleep(0)
 | 
			
		||||
 | 
			
		||||
    if not started and ctnr not in client.containers.list():
 | 
			
		||||
        raise RuntimeError(
 | 
			
		||||
            'Failed to start `marketstore` check logs output for deats'
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    await ctx.started()
 | 
			
		||||
    await tractor.breakpoint()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def main():
 | 
			
		||||
    async with tractor.open_nursery(
 | 
			
		||||
        loglevel='info',
 | 
			
		||||
    ) as tn:
 | 
			
		||||
        portal = await tn.start_actor('ahab', enable_modules=[__name__])
 | 
			
		||||
 | 
			
		||||
        async with portal.open_context(
 | 
			
		||||
            open_marketstore_container
 | 
			
		||||
 | 
			
		||||
        ) as (first, ctx):
 | 
			
		||||
            await trio.sleep_forever()
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    trio.run(main)
 | 
			
		||||
		Loading…
	
		Reference in New Issue