• Как преиодически отправлять данные от сервера клиенту через websocket?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Насколько я понял, вы пытаетесь опрашивать базу данных и выводить изменения, а BSession.GetData() как раз данные из базы получает с помощью SQLAlchemy.

    Во-первых, обращение к базе синхронное и в моменты выполнения запросов будет ставить колом все установленные websocket-соединения. Использовать для решения это проблемы можно sqlalchemy_aio или SQLAlchemy+aiopg. А ещё лучше asyncpg без SQLAlchemy.

    Во-вторых, чтобы пользователи не получали каждый раз всё содержимое базы, стоит хранить где-нибудь последний извлечённый id и запрашивать из базы только записи, у которых id больше.

    Наконец, что касается организации двусторонней асинхронности, должен помочь немного модифицированный вариант из документации:

    async def consumer_handler(websocket, path):
        while True:
            message = await websocket.recv()
            # делаем что-нибудь с сообщением от клиента
    
    
    async def producer_handler(websocket, path):
        while True:
            data = await BSession.GetData()
            if data:
                await websocket.send(data)
    
    
    async def handler(websocket, path):
        consumer_task = asyncio.ensure_future(consumer_handler(websocket))
        producer_task = asyncio.ensure_future(producer_handler(websocket))
        done, pending = await asyncio.wait(
            [consumer_task, producer_task],
            return_when=asyncio.FIRST_COMPLETED,
        )
    
        for task in pending:
            task.cancel()
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(websockets.serve(handler, 'localhost', 8765))
    loop.run_forever()
    Ответ написан
    Комментировать
  • Тестирование продукта на фрилансе?

    nki
    @nki
    bezkart.ru готовая система лояльности
    Надо ли брать потом деньги за доработки?ведь оплата обычно почасовая у программистов
    Вообщем как вы все это регулируете со своими клиентами?

    За доработки деньги брать надо. Свои косяки исправлять за свой счет.
    Со своими клиентами я договариваюсь так - все косяки, которые будут найдены в течении полугода за мой счет.
    Ответ написан
    Комментировать
  • Тестирование продукта на фрилансе?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Поставьте себя на место клиента, вы хотите купить продукт и предполагаете, что он будет качественный. К тому же, количество багов в релизе - это показатель вашего профессионализма и, как следствие, конкурентоспособности. В ваших интересах сводить их к минимуму.
    Ответ написан
    3 комментария
  • Backup сервер на чем лучше организовать windows или Linux (что бы шифровальщик не поработал)?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Под бэкап лучше использовать программно-аппаратные комплексы типа EMC Data Domain.
    Ответ написан
    1 комментарий
  • Как принято реализовывать категории производитедей с количеством товара?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега PostgreSQL
    Седой и строгий
    create table categories (
      id integer primary key,
      parent integer references categories,
      name varchar(50) not null
    );
    
    create table manufacturers (
      id integer primary key,
      name varchar(30) not null
    );
    
    create table goods (
      id integer primary key,
      category integer references categories,
      manufacturer integer references manufacturers,
      name varchar(50) not null
    );
    
    select
      m.name,
      count(*) as goods_count
    from goods as g
    inner join manufacturers as m
      on g.manufacturer = m.id
    where category = 1
    group by m.name;

    Живой пример в sqlfiddle
    Ответ написан
    2 комментария
  • Как ограничить поиск в партиции таблицы?

    Melkij
    @Melkij
    PostgreSQL DBA
    Перепроверил догадку
    melkij=> create table events2016m11 (check (dtime >= '2016-11-01'::date AND dtime < '2016-12-01'::date)) inherits(events);
    melkij=> insert into events2016m11 values ('2016-11-20');
    INSERT 0 1
    melkij=> explain (analyze) select * from events where dtime > '2016-12-05';
                                                       QUERY PLAN                                                   
    ----------------------------------------------------------------------------------------------------------------
     Append  (cost=0.00..38.25 rows=754 width=8) (actual time=0.013..0.013 rows=0 loops=1)
       ->  Seq Scan on events  (cost=0.00..0.00 rows=1 width=8) (actual time=0.004..0.004 rows=0 loops=1)
             Filter: (dtime > '2016-12-05 00:00:00+03'::timestamp with time zone)
       ->  Seq Scan on events2016m11  (cost=0.00..38.25 rows=753 width=8) (actual time=0.009..0.009 rows=0 loops=1)
             Filter: (dtime > '2016-12-05 00:00:00+03'::timestamp with time zone)
             Rows Removed by Filter: 1
     Planning time: 0.127 ms
     Execution time: 0.032 ms
    (8 строк)
    melkij=> drop table events2016m11 ;
    DROP TABLE
    melkij=> create table events2016m11 (check (dtime >= '2016-11-01'::timestamptz AND dtime < '2016-12-01'::timestamptz)) inherits(events);
    CREATE TABLE
    melkij=> insert into events2016m11 values ('2016-11-20');INSERT 0 1
    melkij=> explain (analyze) select * from events where dtime > '2016-12-05';                                              QUERY PLAN                                              
    ------------------------------------------------------------------------------------------------------
     Append  (cost=0.00..0.00 rows=1 width=8) (actual time=0.004..0.004 rows=0 loops=1)
       ->  Seq Scan on events  (cost=0.00..0.00 rows=1 width=8) (actual time=0.004..0.004 rows=0 loops=1)
             Filter: (dtime > '2016-12-05 00:00:00+03'::timestamp with time zone)
     Planning time: 0.301 ms
     Execution time: 0.024 ms
    (5 строк)
    
    melkij=> show constraint_exclusion ;
     constraint_exclusion 
    ----------------------
     partition

    Внимательнее с явным приведением типов. У планировщика достаточно работы и не всё эквивалентное он считает идентичным. К тому же timestamp with timezone и date (без времени вовсе) надо сравнивать аккуратно.
    Ответ написан
    Комментировать
  • Как хранить базу postgres 8.4 в памяти?

    Melkij
    @Melkij
    PostgreSQL DBA
    Закупаете железку с 256гб ram и выше. Ставите shared_buffers в 200гб. Всё. Со временем все данные к каким обращались будут подтянуты в память. А поскольку буферов больше чем база - база их не будет вытеснять из памяти.

    Можно было бы воспользоваться pg_prewarm для более удобного подтягивания данных в память после старта СУБД - да у вас какая-то ископаемая, давно уже не поддерживаемая версия. pg_prewarm для такой древности нет. (если, конечно, вы не опечатались в 9.4)
    Для такого объёма shared_buffers желательно huge pages сделать по объёму на пару процентов больше чем shared_buffers. А вот как - может для 8.4 и никак, я не настолько старый DBA, не знаю.
    Ответ написан
    4 комментария
  • Postgresql как ограничить общий размер WAL-файлов?

    Melkij
    @Melkij
    PostgreSQL DBA
    Один сегмент WAL обычно имеет фиксированный размер 16мб (опция компиляции postgresql with-wal-segsize, если вы её указывали - вы должны об этом знать, плюс она требует initdb делать заново). Поэтому их количество пересчитывается в объём банальным умножением.

    Ограничить максимальный занимаемый объём wal сверху - нельзя. Такой единой гайки нет, даже если вас устраивает переход базы в readonly по достижении этого лимита. И есть довольно много гаек, которые при своём использовании могут попросить базу не вычищать старые wal ещё какое-то время.

    Гайки, на которые надо обращать внимание:
    wal_keep_segments - база оставляет на диске не меньше этого числа wal, что позволяет реплике штатно на некоторое время терять мастера и затем догонять
    replication slots - если вы сделаете слот репликации и его никто не будет читать - база будет сохранять wal пока не закончится диск. Если вы используете слоты репликации, то у вас в мониторинге обязана быть отдельная проверка что слот вычитывается
    max_wal_size - несмотря на название - объём wal, по накоплению которого происходит checkpoint. (либо по таймеру checkpoint_timeout смотря что случится раньше). Реально объём wal может быть выше, т.к. автоматический checkpoint намеренно не выполняется моментально, а размазан во времени.
    min_wal_size - этот объём wal всегда будет на диске занят и будет переписываться по кругу. Как гарантия того, что на диске есть место под столько wal
    archive_command - если включен и команда возвращает ненулевой статус возврата - то будет накапливать wal без ограничений. wal будут удалены (если только ещё не нужны какой из других настроек) когда archive_command получает от команды 0 код возврата.

    Если не хочется много денег тратить на резерв свободного места на хороших SSD - разместите на SSD саму базу данных, а WAL перенесите (симлинком директории pg_xlog (до 10.0) или pg_wal (10.0 и выше)) на отдельные HDD. WAL пишутся строго последовательно, вполне возможно жить с WAL на механических дисках и держать хорошую нагрузку.
    Плюс если работаете не с деньгами, можно сделать synchronous_commit = off. Что увеличит производительность всех пишущих транзакций. Но в случае фатального краха железа вы потеряете последние 3*wal_writer_delay транзакции (т.е. до 3*200мс = 600мс).
    Ответ написан
    2 комментария
  • Достаточно ли надёжны security groups?

    @yellowmew
    Cloud infrastructure, monitoring engineer. SRE
    Если есть сомнения в безопасности - значит надо настраивать дополнительный уровень :D
    AWS предоставляет два уровня безопасности в VPC :
    Network ACL и Security Groups
    Первые служат для ограничения доступа между подсетями, вторые - между сетевыми интерфейсами в VPC
    Несмотря на то, что Между ними есть довольно сильная разница в поведении\применении (описана в таблице docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC... ) выполняют они примерно одну и ту же функцию.
    Как дополнительная возможность безопасности(рекомендуемая AWS в вышеуказанной статье) - внутренний firewall вашей OS может закрыть link-local( 169.254.x.x) и трафик на первые 4 адреса вашего VPC (внутренний функционал AWS, этот трафик даже не отслеживается с помошью flow logs, не то что контролируется).

    Однако же, рекомендуется firewall внутри инстанса все же настраивать соответственно вашим правилам.
    Безопасности мало не бывает, а для того чтобы правила на всех слоях безопаности соответствовали - используйте IAAC.

    Ах да, ответ на вопрос : Достаточно надёжны.
    Ответ написан
    Комментировать
  • Как сделать join из другой таблицы в виде JSON массива?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега SQL
    Седой и строгий
    select
      u.*,
      group_concat(json_object('id', p.id, 'summ', p.summ, 'status', p.status)) as payments_json
    from user as u
    inner join payments as p
      on u.id = p.user_id
    group by u.id, u.name;
    Ответ написан
    Комментировать
  • PostgreSQL bigint и int в качестве PK?

    nazarpc
    @nazarpc
    Open Source enthusiast
    Да, нормально. И да, можете изменить после, но учтите что для больших таблиц это может занять продолжительное время.
    Ответ написан
    Комментировать
  • Можно ли в Select обрезать строку если она привышает заданное кол-во символов?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега PostgreSQL
    Седой и строгий
    select
      case 
        when char_length(some_field) > 15 then substring(some_field from 0 for 15) || '...'
        else some_field
      end
    from some_table;
    Ответ написан
    Комментировать
  • Можно ли поставить интернет магазин на Sqlite3?

    sim3x
    @sim3x
    Можно
    Но не нужно
    Используйте постгрес
    Ответ написан
    Комментировать
  • Различия между Postgresql и Mysql?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега PostgreSQL
    Седой и строгий
    Самое главное отличие - PostgreSQL поддерживает современный стандарт SQL:2008, а MySQL не в полном объёме даже SQL-92.
    Ответ написан
    5 комментариев
  • В чем причина ошибки при компиляции clojurescript?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Clojure
    Седой и строгий
    У макроса ns пропущена закрывающая скобка. И приведите версии зависимостей к актуальным:
    (defproject spa-tutorial "0.1.0-SNAPSHOT"
      :description "FIXME: write this!"
      :url "http://example.com/FIXME"
    
      :dependencies [[org.clojure/clojure "1.8.0"]
                     [org.clojure/clojurescript "1.9.521"]
                     [org.clojure/core.async "0.3.442"]
                     [org.omcljs/om "0.9.0"]
                     [prismatic/om-tools "0.4.0"]
                     [http-kit "2.3.0-alpha2"]
                     [secretary "1.2.3"]]
    
      :plugins [[lein-cljsbuild "1.1.6"]]
    
      :source-paths ["src" "target/classes"]
    
      :clean-targets ["out/spa_tutorial" "out/spa_tutorial.js"]
    
      :cljsbuild {
        :builds [{:id "spa-tutorial"
                  :source-paths ["src"]
                  :compiler {
                    :main spa-tutorial.core
                    :output-to "out/spa_tutorial.js"
                    :output-dir "out"
                    :optimizations :none
                    :verbose true}}]})

    Проверил у себя, трансляция проходит нормально.
    Ответ написан
    6 комментариев
  • Как передать в stringio данные stdout?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Django
    Седой и строгий
    Ну и зачем эти костыли? Если вам надо получить json всех данных проекта, используйте сериализатор, как это делает сама команда dumpdata:
    from django.apps import apps
    from django.core import serializers
    
    # Получаем список всех моделей всех приложений из INSTALLED_APPS
    # и фильтруем django'вские
    models = [model for model in apps.get_models() if not model.__module__.startswith('django')]
    
    # Сериалзиуем в json полный QuerySet каждой модели
    dump = ''
    for m in models:
        dump += serializers.serialize('json', m._default_manager.all())
    Ответ написан
    Комментировать
  • Как отправить POST запрос на URL по средствам Cisco TCL?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    source "tmpsys:lib/tcl/http.tcl"
    ::http::geturl http://example.com/ -query [::http::formatQuery "param-name" "param-value"]
    Ответ написан
    2 комментария
  • Как программно удалить номер телефона контакта?

    TrueBers
    @TrueBers
    Гуглю за еду
    На developer.android.com примера нет
    ага, у этих негодяев ваще ничего нет, зачем они только живут?..
    Ответ написан
    1 комментарий
  • Как выбрать все нижестоящие категории?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега PostgreSQL
    Седой и строгий
    Используйте рекурсивный CTE:
    with recursive r as (
        select
          id, parent_id, name
        from catalog_category
        where id = 8
      union
        select
          cc.id, cc.parent_id, cc.name
        from catalog_category as cc
        join r
          on cc.parent_id = r.id
    )
    select id, name from r where id <> 8;

    Этот запрос выбирает все категории дочерние по отношению к категории с ID = 8.
    Ответ написан
    1 комментарий