All streams
Search
Write a publication
Pull to refresh
1
0
Send message

В этом случае мы пробуем такой подход: выносим логику всей авторизации в сервис на основе Open Policy Agent. И все проверки делает через него.

Для тех случаев, когда нужна производительность - тогда используем partial evaluation и генерим sql предикаты.

Если интересно - можно поискать по таким словам:

  • How Miro leverages Open Policy Agent to implement authorization-as-a-service

  • AWS Prescriptive Guidance - Multi-tenant SaaS authorization and API access control

  • How to build authorization like Netflix with Open Source?

  • Write Policy in OPA. Enforce Policy in SQL.

А как вы понимаете, какая функцию какую вызывает в классе А (ведь все уже скомпилировано)? Ведь там может быть сколь угодно жуткая логика, не?

Как это будет работать вот для такого случая (для многократных вызовов fun1). Не будет ли иногда в стектрейсе лишнего fun2?

suspend fun fun1() {
    if ((0..1).random() == 0) {
      fun2("throw fun2")
    } else {
      fun3("directly fun3")
    }
    delay(10)
}

suspend fun fun2(x: String) {
    fun3(x)
    delay(10)
}

suspend fun fun3(x: String) {
    delay(10)
    throw Exception(x)
}

Выглядит очень заманчиво, но хотелось бы больше деталей о реализации - пока что-то непонятно. Зачем классы-заглушки? Сколько их генериться? Когда? Можно же, наверное, создать руками любой стектрейс, не?

Я использую вот такую кверю (она считает разницу прямо в запросе с 20-секундой паузой).

Кроме того, она схлопывает запросы с различным количеством параметров вместе посредством регулярки.

SELECT
   round(sum(total_time))                                          AS total,
   round(sum(calls))                                               AS calls,
   round(sum(total_time) / sum(calls))                             AS per_query,
   regexp_replace(query, '(\$[0-9]+\s*,?\s*)+', '$$ ', 'g') AS query_group
FROM (WITH
    p AS (
      SELECT 20.0
  ),
    t AS (
      SELECT sum(calls) as calls, queryid, max(query) as query, sum(total_time) as total_time FROM pg_stat_statements      
      group by queryid
  ),
  s AS (
      SELECT * FROM pg_sleep((SELECT * FROM p limit 1) + (SELECT count(*) FROM t) * 0.0001)
  ),
    r AS (
      SELECT sum(calls) as calls, queryid, max(query) as query, sum(total_time) as total_time
      FROM s,
           pg_stat_statements
      group by queryid
  )
SELECT coalesce(r.queryid, t.queryid)                             AS queryid,
       coalesce(r.query, t.query)                                 AS query,
       abs(coalesce(r.calls, 0) - coalesce(t.calls, 0))           AS calls,
       abs(coalesce(r.total_time, 0) - coalesce(t.total_time, 0)) AS total_time
FROM t inner
       JOIN r ON (t.queryid = r.queryid)
WHERE coalesce(r.calls, 0) - coalesce(t.calls, 0) != 0)  
         AS s
GROUP BY regexp_replace(query, '(\$[0-9]+\s*,?\s*)+', '$$ ', 'g')
ORDER BY sum(total_time) DESC

Об очень похожем метода мы рассказывали совсем недавно на YaTalks — https://youtu.be/hXH_tRBxFnA 05:02:53 (извиняюсь не смог с телефона получить точную ссылку — секция про очереди, доклад "Как Толока росла вместе с кластером PostgreSQL").

Information

Rating
Does not participate
Registered
Activity