Ir para o conteúdo
KAMOUniverse

Changelog

O que há de novo.

Cada melhoria para a plataforma, como ele envia.

  1. · KBService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Cada varredura @Scheduled aqui cujo efeito é compartilhado agora leva um nome de locação distribuída através SingletonTaskRunner antes de fazer qualquer coisa, então ele corre uma vez através da frota em vez de uma vez por pod. Essa foi a única coisa que manteve este serviço em uma réplica — não há nenhum ShedLock em qualquer lugar Esta plataforma, então a contagem de réplicas foi o que fez as varreduras corretas. @Transacional e amigos permanecem no método EXTERIOR onde presente: Primavera aplica-los com um proxy, e o método interno é alcançado através de um:: referência, que nunca passa por um. Movê-los para dentro deixaria a varredura silenciosamente não-transacional. réplicas 1 -> 2, com um PodDisruptionBudget em KlusterServices para que um dreno de nó espere.

  2. · ESigService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Cada varredura @Scheduled aqui cujo efeito é compartilhado agora leva um nome de locação distribuída através SingletonTaskRunner antes de fazer qualquer coisa, então ele corre uma vez através da frota em vez de uma vez por pod. Essa foi a única coisa que manteve este serviço em uma réplica — não há nenhum ShedLock em qualquer lugar Esta plataforma, então a contagem de réplicas foi o que fez as varreduras corretas. @Transacional e amigos permanecem no método EXTERIOR onde presente: Primavera aplica-los com um proxy, e o método interno é alcançado através de um:: referência, que nunca passa por um. Movê-los para dentro deixaria a varredura silenciosamente não-transacional. réplicas 1 -> 2, com um PodDisruptionBudget em KlusterServices para que um dreno de nó espere.

  3. · AIService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Cada varredura @Scheduled aqui cujo efeito é compartilhado agora leva um nome de locação distribuída através SingletonTaskRunner antes de fazer qualquer coisa, então ele corre uma vez através da frota em vez de uma vez por pod. Essa foi a única coisa que manteve este serviço em uma réplica — não há nenhum ShedLock em qualquer lugar Esta plataforma, então a contagem de réplicas foi o que fez as varreduras corretas. @Transacional e amigos permanecem no método EXTERIOR onde presente: Primavera aplica-los com um proxy, e o método interno é alcançado através de um:: referência, que nunca passa por um. Movê-los para dentro deixaria a varredura silenciosamente não-transacional. réplicas 1 -> 2, com um PodDisruptionBudget em KlusterServices para que um dreno de nó espere.

  4. · kamo-internal

    sessões de codificador ao lado das shells em execução, e uma barra de rolagem que atinge ambas as extremidades

    # # Terminais agora são duas vistas de uma máquina Sub-tabs em vez de duas abas de nível superior, porque não são dois destinos: um terminal é uma shell que pode estar executando uma sessão, uma sessão é uma conversa que pode ter uma concha. O interruptor é um controle segmentado, não uma segunda aba MUI tira — duas barras de tabulação empilhadas lidas como cromadas, um trilho segmentado lê como "uma das Estes dois", que é o que é. Cada metade carrega sua própria criação, então um único `+` no cabeçalho navegador (que só poderia significar um deles) é agora mostrado apenas durante o colapso, onde nenhuma linha se encaixa. TerminalsWorkbench é compartilhado pelo Centro de Interação e o maximizado navegador, exatamente como Terminais Pane já estava, então os dois não podem se desviar. Ele toma a lista de terminais como um adereço em vez de votar novamente — ambas as superfícies Já o segurei. # # Dois verbos, e qual deles aparece É o estado Uma sessão já em execução em um terminal diz **Open** e levanta essa janela. Um que não é diz **Resuma** e abre um terminal que o pega de volta. Nunca as duas coisas, e nunca uma fila de deficientes. Continuando uma sessão que já está Anexado dá uma conversa duas cabeças: ambos CLIs escrever para o mesmo A transcrição e a segunda se abrem, repetindo o que a primeira está no meio. A regra é uma função, 'terminalForSession', para que nada possa respondê-la duas vezes e diferente. a máquina deixa um recibo no momento em que prepara um — e assim o diz do que oferecer-se para retomar algo que ainda não foi escrito. As sessões são agrupadas por dia. Quatrocentos deles em uma coluna plana é uma parede; os mesmos quatrocentos em Hoje / Ontem / No início desta semana / Antes disso é uma lista que pode encontrar ontem à tarde. A lista mantém os arredores regras: a mesma geometria da linha e trilho 3px que a lista de terminais, e o mesmo divisão tipográfica — o que uma pessoa ou o modelo escreveu está definido na interface sans, o que a máquina relata está definido no mono do emulador. Nada aqui pode pedir um modo de permissão. Cada sessão começa com permissões ignoradas e que é decidido na máquina dev; os nomes da solicitação que sessão e nada mais. Um pinos de teste que o cliente não pode crescer parâmetro. # # A própria barra de rolagem do terminal xterm desenha a barra cinza do navegador em seu viewport, que só pode oferecer "um pouco Para cima e para baixo. Num terminal, as duas extremidades não são mais duas posições — eles são os dois lugares que você realmente quer, o início do que você correu e o live prompt - assim cada um recebe um botão: pule-para-iniciar acima da seta para cima, saltar para a ponta abaixo da seta para baixo, com a repetição de pressionar e segurar nas setas, click-to-page na faixa e um polegar arrastável. O próprio bar do xterm está escondido, não restyled; o viewport ainda rola, então roda, trackpad e toque estão inalterados. As luzes do botão saltar-para-fim quando a saída chegou abaixo da dobra. Um terminal que parou de seguir parece exatamente como um que terminou, e que é a única coisa que o bar sabe que o leitor não pode ver. # # Verificação O portão completo: 14 guardas fonte e 5322 testes, mais tsc. A nova UI também foi renderizado em um navegador de um arnês local e lido em vez de assumido — que pegou um chip de verbo transparente mostrando o título truncado através da palavra "Resuma", e um estado vazio que piscava sobre uma máquina com quatrocentos sessões porque 'loading' ainda é falso na renderização antes do efeito ser executado. axe-core relata zero violações WCAG AA através dos novos componentes. A workbench carrega seu próprio MotionConfig: o Interaction Center envolve seu painel em um, o navegador não faz, e framer-motion fora um anima reta através do movimento de preferência reduzida sem uma palavra. As chaves do dicionário caíram primeiro, como o CI exige.

  5. · SecurityService

    Listar as sessões de codificação de um membro e abrir uma num terminal

    Dois terminais ao lado dos terminais, e eles seguem a mesma regra que aqueles fazem: a conta Linux é resolvida a partir da SESSÃO PRÓPRIA DO CALAR e sem nome da conta é sempre retirado do pedido. Um membro só pode, portanto, ver ou reabrir o seu Sessões próprias — não há identificação que possam fornecer que chegue a alguém Porque a conta não faz parte do que eles fornecem. máquina de dev inalcançável volta 200 com `inalcançável: true' e um vazio lista, como a listagem do terminal faz: "a máquina está para baixo" é algo que a aba pode dizer, onde um erro o deixa capaz de dizer nada. nova sessão ou retoma uma existente. Nada corre quando o POST retorna. A máquina escreve a sessão e devolve um recibo; a janela do terminal que a consola abre a seguir apresenta a sua bilhete comum, e o recibo é o que transforma esse terminal nesta sessão — o mesmo send-to-AI usa, através do mesmo TerminalDispatchRegistry. O ID da janela é nomeado AQUI porque ambas as metades precisam dele: o console para abrir o janela, o registro para teclar o recibo, e tmux para sobreviver ao reconectá-lo existe para permitir. Este endpoint não pode expressar um comando, um modelo, um esforço ou um modo de permissão. Cada uma delas é a máquina a decidir. O que cruza o fio é que sessão, e nada mais — assim “permissões bypass”, que cada um destes sessões corre com, não é um parâmetro aqui e não pode se tornar um. TerminalResumo cresce `coderSessionId`: a sessão uma shell está sendo executada, lida fora da opção de usuário tmux que o agente define. É o que deixa o console dizer "já aberto" em vez de retomar uma conversa que está ao vivo em outro Não há outro sítio de onde isto possa vir. Abrir um é auditado exatamente como abrir um shell é — mesmo tipo de evento, mesmo ALTA severidade — porque é uma. Verificado com `mvn test`; Java CI não executa nenhum, então um repo vermelho ainda iria implantar.

  6. · KlusterServices

    Medir se um implante realmente custa a alguém um pedido

    Cada correção neste programa é uma reivindicação sobre o que acontece durante uma implantação. Até agora, essas alegações não foram testados: MediaService enviado com estratégia Recriar em uma réplica para toda a sua vida, assim cada implantação deletou o único pod que serve chat e anexos e iniciou a substituição depois — um ~65 segundo buraco, várias vezes por dia — e nada o mediu. A primeira pessoa sabia que era um membro que relatou um envio de documento falhado, e até mesmo que lido como uma característica flácida em vez do que como bate-papo estar em baixo em um horário. Um exportador de caixas pretas agora carrega os oito anfitriões públicos a cada 10 segundos. Dez, não os 30s padrão: a falha que existe para capturar é curta por projeto, e aos 30s um gráfico limpo significaria apenas O buraco caiu entre dois arranhões. Dois alertas importam, e o segundo é o mais útil: PublicHostDown um anfitrião não respondeu por um minuto. Uma falha, lançar ou não. PublicHostFlapping abaixo de 100% de sucesso ao longo de dez minutos. Este é o que apanha um lançamento deixando cair um punhado de pedidos — recupera muito antes de um 1m 'for' ocorrer, que é precisamente por isso que essa falha é reportada como 'ele me registrou aleatoriamente E nunca como um incidente. Além de um alerta de certificado (a falha auto-assinada de Traefik a frio não tinha nenhum detector), um preso alerta de implantação, e um para uma implantação sentado abaixo da contagem de réplicas desejada — porque réplicas: 2 só ajuda enquanto o segundo pod está realmente para cima, e um que não parece saudável. Verificação TLS é deliberadamente sobre: um certificado esta plataforma serve erradamente deve falhar o sonda, uma vez que é exatamente o que um Traefik frio costumava fazer a cada org ao mesmo tempo. monitoramento / não é um alvo de aplicação de IC por convenção de longa data aqui, então ambos os arquivos carregam linha própria de aplicação.

  7. · KlusterServices

    sessões de codificador na máquina de dev, listadas e reutilizáveis

    está aqui, porque a máquina é a única coisa que sabe alguma coisa. # # O índice de sessão Em casa, exactamente como os terminais deles são o que quer que o Tmux esteja a funcionar. Sem mesa, para mesma razão: o disco já sabe, é o que o próprio CLI retoma, e Memoized on (tempo, tamanho), e tem que ser — a máquina que foi construída contra realiza 444 sessões e 1.1 GB de transcrição, uma delas 205 MB. Apenas o primeiro e último 128 KB de cada arquivo são lidos: o diretório de trabalho, o branch e o prompt de abertura está nos primeiros registros, o título gerado e o resumo são adicionado como a sessão continua, e o meio é chamadas de ferramenta. Medida contra a loja real: 2.8s frio, 17ms quente. # # Duas coisas que uma transcrição não pode dizer Uma transcrição não grava que o console começou, então uma sessão começou sem ela a linha que um membro criado está faltando na lista que eles estão olhando para, que lê como o botão não ter feito nada. E uma transcrição não registra de onde está sendo conduzido, então uma concha que está executando um agora carrega o ID de sessão como uma opção de usuário tmux (@kamo coder), ao lado do título que já lá vive. Essa é toda a regra duplicada: retomar uma sessão que já está anexada dá uma conversa duas cabeças, com ambos os CLIs escrevendo para uma transcrição ea segunda replaying o que o primeiro Está no meio. A listagem, portanto, cresce um campo, então `list-sessions -F' agora pede sete — o título permanece por último e a divisão permanece limitada, porque o separador é imprimível e um membro pode digitá-lo. # # O chamador ainda nunca fornece um comando A linha de comando é composta aqui: o caminho do CLI resolvido sob a conta casa própria, o id de sessão cunhado ou encontrado neste disco, e `--permissão-modo bypassPermissions`, que não é um parâmetro e não pode ser Uma. Registros preparados agora carregam uma espécie, e um que antecede o campo é um Envio para a IA, que era o único tipo que havia. O diretório de trabalho é a única coisa que um pedido pode influenciar e é limitado por Um verdadeiro caminho para a própria casa da conta. Este não é um limite de privilégio — o terminal já roda como essa conta — mantém o conjunto de diretórios a PEDIDO pode nomear menor do que o conjunto que uma pessoa pode alcançar. Um registro que nomeia A conta também só é recuperável pelo terminal dessa conta. 40 novos testes, 199 na suite, todos a passar. O índice é verificado Uma verdadeira loja 444-sessão em vez de instalações só. Navios por install-agent.sh, não por CI: empurrando isso não coloca nada na VM.

  8. · KlusterServices

    Orçamento cada dreno, e falha uma implantação que regride a segurança de implantação

    PodDisruptionOrçamentos para as 25 Implantações que agora executam genuinamente duas réplicas. minDisponível: 1 deixa um dreno despejar uma cápsula e esperar pela sua substituição em vez de levar um nó inteiro para baixo imediatamente. O espaço de nomes kamo tinha ZERO destes enquanto cluster-services, kamo-universo, rattack, longhorn-system e kubevirt todos os tinham — o namespace que mantinha a produção era aquele sem. Só aparecem destacamentos em duas réplicas. Um PDB em uma única réplica A implantação é pior do que nenhum: minDisponível: 1 contra réplicas: 1 permite rompimentos zero, por isso não protege o carga de trabalho, bloqueia a manutenção do nó para sempre. README.md diz isso, e nomeia o deliberado Singletons que nunca devem ser listados. scripts/audit-deploy-safety.sh falha a implantação se uma implantação no kamo tiver voltado para uma forma que deixa cair pedidos durante um lançamento: nenhuma sonda de prontidão, nenhum gancho preStop, nenhum minProntoSegundos, Recriar sem um opt-out, ou duas réplicas sem nada espalhando-os pelos nós. Audita o CLUSTER em vez dos manifestos. Essas configurações vivem em 48 repositórios separados com 48 fluxos de trabalho; um guarda per-repo pegaria uma regressão mais cedo, mas são 48 cópias para manter em passo e qualquer acordo que nunca adote é silenciosamente isento. Cada um desses manifestos acaba Aqui. O comércio é que é um alarme de fumo em vez de uma fechadura — relata depois do facto, por isso imprime toda a mesa e nomes que derivaram em vez de apenas falhar. Isenções são anotações sobre a própria implantação e uma razão é obrigatória: uma isenção sem um é um fracasso. Isso é o que permite que a próxima pessoa dizer um singleton deliberado (kamodaemon liga a duráveis NATS exclusivas) de algo que ninguém conseguiu.

  9. · RAGService

    Compartilhe os consumidores indexando, e execute dois pods

    RAGService liga dois JetStream duráveis próprios — rag-note-consumidor e rag-kb-consumidor — e um consumidor de push durável sem grupo de entrega admite exatamente um assinante. Uma segunda cápsula seria foram recusados [SUB-90012], deixando a indexação fixada à primeira cápsula com Nada a assumir quando a cápsula morre. Ambos agora se juntam a um grupo de entrega, então o NATS entrega cada evento a exatamente uma cápsula. Isso é o que indexação necessidades: uma vez, nem uma vez por pod, e nem uma vez por pod que aconteceu para ganhar uma corrida. réplicas 1 -> 2. Este serviço não executa nenhum trabalho @Scheduled e não liga nenhum exclusivo NATS durável, assim um segunda cápsula duplica nada — é pedido apátrida servindo, e a única coisa mantendo-o em uma réplica era que nada tinha aumentado o número. Em uma réplica maxSurge esconde a exposição durante uma implantação limpa e em nenhum outro lugar: uma morte OOM, um sonda de vida falhada ou um dreno de nó tirou a capacidade inteiramente para o 59-79 segundos a O contexto da primavera leva ao arranque. Um PodDisruptionBudget em KlusterServices agora faz um dreno esperar.

  10. · VectorService

    Executar duas cápsulas

    réplicas 1 -> 2. Este serviço não executa nenhum trabalho @Scheduled e não liga nenhum exclusivo NATS durável, assim um segunda cápsula duplica nada — é pedido apátrida servindo, e a única coisa mantendo-o em uma réplica era que nada tinha aumentado o número. Em uma réplica maxSurge esconde a exposição durante uma implantação limpa e em nenhum outro lugar: uma morte OOM, um sonda de vida falhada ou um dreno de nó tirou a capacidade inteiramente para o 59-79 segundos a O contexto da primavera leva ao arranque. Um PodDisruptionBudget em KlusterServices agora faz um dreno esperar.

  11. · ConversionService

    Executar duas cápsulas

    réplicas 1 -> 2. Este serviço não executa nenhum trabalho @Scheduled e não liga nenhum exclusivo NATS durável, assim um segunda cápsula duplica nada — é pedido apátrida servindo, e a única coisa mantendo-o em uma réplica era que nada tinha aumentado o número. Em uma réplica maxSurge esconde a exposição durante uma implantação limpa e em nenhum outro lugar: uma morte OOM, um sonda de vida falhada ou um dreno de nó tirou a capacidade inteiramente para o 59-79 segundos a O contexto da primavera leva ao arranque. Um PodDisruptionBudget em KlusterServices agora faz um dreno esperar.

  12. · APIService

    Executar duas cápsulas

    réplicas 1 -> 2. Este serviço não executa nenhum trabalho @Scheduled e não liga nenhum exclusivo NATS durável, assim um segunda cápsula duplica nada — é pedido apátrida servindo, e a única coisa mantendo-o em uma réplica era que nada tinha aumentado o número. Em uma réplica maxSurge esconde a exposição durante uma implantação limpa e em nenhum outro lugar: uma morte OOM, um sonda de vida falhada ou um dreno de nó tirou a capacidade inteiramente para o 59-79 segundos a O contexto da primavera leva ao arranque. Um PodDisruptionBudget em KlusterServices agora faz um dreno esperar.

  13. · kamo-internal

    Responda a uma sonda de prontidão e execute duas cápsulas

    Esta implantação não tinha nenhuma sonda de prontidão, então uma cápsula contada como Pronto no instante em que o seu recipiente processo iniciado. Com maxIndisponível 0 Kubernetes lê que como "o novo pod está servindo" e retira-se o antigo — enquanto o Next ainda está a inicializar e não ligou o seu porto. Pedidos desembarcados em um porto nada estava ouvindo em, que é de onde os 502s intermitentes em implantação vieram. /api/saúde responde apenas para esta cápsula e deliberadamente não toca nenhuma infra-estrutura: uma sonda de prontidão decide se este pod deixa o Serviço, e fiação para uma infra- estrutura transforma um blip de infra- estrutura em uma A reiniciar cada cápsula aqui. O dreno e o período de graça 660 já estavam aqui; a sonda em falta foi o que os deteve Contagem. Kubernetes estava a retirar a cápsula de drenagem antes da substituição poder servir. réplicas 1 -> 2. O estado do servidor vive em Redis, não no pod, e não há trabalho agendado para duplicar, então uma segunda réplica não muda nada exceto que perder uma cápsula deixa de ser uma falha. Em uma réplica uma morte OOM, uma sonda de vida falhada ou um dreno de nó levou tudo para baixo para O tempo que for preciso para arrancar. topologiaSpreadConstraints (adicionado mais cedo, inerte até agora) manter os dois em nós diferentes onde o cluster pode gerenciá-lo, e um PodDisruptionBudget no KlusterServices faz um dreno esperar.

  14. · kamo-marketing

    Drinque no SIGTERM, e execute duas cápsulas

    Em seguida, lida com o SIGTERM com um process.exit nu(143), então cada implantação cortou o que quer que este pod tinha em vôo — uma postagem de formulário, uma ação do servidor, uma carga útil RSC transmitida, um upload. Invisível quando uma a requisição durou milissegundos; não invisível em um cluster que é implantado em cada push. scripts/standalone-entry.cjs envolve o servidor standalone: no SIGTERM ele pára de aceitar, deixa inativo manter-vivos de uma vez para que uma cápsula sem nada em vôo ainda sai em cerca de um segundo, e vamos correr Os pedidos terminam sob uma tampa que fica abaixo da terminaçãoGracePeriodSeconds. Portados de Kamo-internal, que a tem executado em produção há meses. O wrapper inicia server-nonce.js em vez de server.js, através do NEXT SERVER ENTRY — o nonce CSP O servidor fica exactamente onde estava na corrente. réplicas 1 -> 2. O estado do servidor vive em Redis, não no pod, e não há trabalho agendado para duplicar, então uma segunda réplica não muda nada exceto que perder uma cápsula deixa de ser uma falha. Em uma réplica uma morte OOM, uma sonda de vida falhada ou um dreno de nó levou tudo para baixo para O tempo que for preciso para arrancar. topologiaSpreadConstraints (adicionado mais cedo, inerte até agora) manter os dois em nós diferentes onde o cluster pode gerenciá-lo, e um PodDisruptionBudget no KlusterServices faz um dreno esperar.

  15. · kamo-capcha

    Executar duas cápsulas

    réplicas 1 -> 2. O estado do servidor vive em Redis, não no pod, e não há trabalho agendado para duplicar, então uma segunda réplica não muda nada exceto que perder uma cápsula deixa de ser uma falha. Em uma réplica uma morte OOM, uma sonda de vida falhada ou um dreno de nó levou tudo para baixo para O tempo que for preciso para arrancar. topologiaSpreadConstraints (adicionado mais cedo, inerte até agora) manter os dois em nós diferentes onde o cluster pode gerenciá-lo, e um PodDisruptionBudget no KlusterServices faz um dreno esperar.

  16. · kamo-register

    Drinque no SIGTERM, responda a uma sonda de prontidão, e execute duas cápsulas

    Em seguida, lida com o SIGTERM com um process.exit nu(143), então cada implantação cortou o que quer que este pod tinha em vôo — uma postagem de formulário, uma ação do servidor, uma carga útil RSC transmitida, um upload. Invisível quando uma a requisição durou milissegundos; não invisível em um cluster que é implantado em cada push. scripts/standalone-entry.cjs envolve o servidor standalone: no SIGTERM ele pára de aceitar, deixa inativo manter-vivos de uma vez para que uma cápsula sem nada em vôo ainda sai em cerca de um segundo, e vamos correr Os pedidos terminam sob uma tampa que fica abaixo da terminaçãoGracePeriodSeconds. Portados de Kamo-internal, que a tem executado em produção há meses. Esta implantação não tinha nenhuma sonda de prontidão, então uma cápsula contada como Pronto no instante em que o seu recipiente processo iniciado. Com maxIndisponível 0 Kubernetes lê que como "o novo pod está servindo" e retira-se o antigo — enquanto o Next ainda está a inicializar e não ligou o seu porto. Pedidos desembarcados em um porto nada estava ouvindo em, que é de onde os 502s intermitentes em implantação vieram. /api/saúde responde apenas para esta cápsula e deliberadamente não toca nenhuma infra-estrutura: uma sonda de prontidão decide se este pod deixa o Serviço, e fiação para uma infra- estrutura transforma um blip de infra- estrutura em uma A reiniciar cada cápsula aqui. O Dockerfile HEALTHCHECK tem apontado para /api/saúde desde que foi escrito; a rota não existe, de modo que o controlo tem falhado desde que lá esteve. réplicas 1 -> 2. O estado do servidor vive em Redis, não no pod, e não há trabalho agendado para duplicar, então uma segunda réplica não muda nada exceto que perder uma cápsula deixa de ser uma falha. Em uma réplica uma morte OOM, uma sonda de vida falhada ou um dreno de nó levou tudo para baixo para O tempo que for preciso para arrancar. topologiaSpreadConstraints (adicionado mais cedo, inerte até agora) manter os dois em nós diferentes onde o cluster pode gerenciá-lo, e um PodDisruptionBudget no KlusterServices faz um dreno esperar.

  17. · kamo-login

    Drinque no SIGTERM, responda a uma sonda de prontidão, e execute duas cápsulas

    Em seguida, lida com o SIGTERM com um process.exit nu(143), então cada implantação cortou o que quer que este pod tinha em vôo — uma postagem de formulário, uma ação do servidor, uma carga útil RSC transmitida, um upload. Invisível quando uma a requisição durou milissegundos; não invisível em um cluster que é implantado em cada push. scripts/standalone-entry.cjs envolve o servidor standalone: no SIGTERM ele pára de aceitar, deixa inativo manter-vivos de uma vez para que uma cápsula sem nada em vôo ainda sai em cerca de um segundo, e vamos correr Os pedidos terminam sob uma tampa que fica abaixo da terminaçãoGracePeriodSeconds. Portados de Kamo-internal, que a tem executado em produção há meses. Esta implantação não tinha nenhuma sonda de prontidão, então uma cápsula contada como Pronto no instante em que o seu recipiente processo iniciado. Com maxIndisponível 0 Kubernetes lê que como "o novo pod está servindo" e retira-se o antigo — enquanto o Next ainda está a inicializar e não ligou o seu porto. Pedidos desembarcados em um porto nada estava ouvindo em, que é de onde os 502s intermitentes em implantação vieram. /api/saúde responde apenas para esta cápsula e deliberadamente não toca nenhuma infra-estrutura: uma sonda de prontidão decide se este pod deixa o Serviço, e fiação para uma infra- estrutura transforma um blip de infra- estrutura em uma A reiniciar cada cápsula aqui. réplicas 1 -> 2. O estado do servidor vive em Redis, não no pod, e não há trabalho agendado para duplicar, então uma segunda réplica não muda nada exceto que perder uma cápsula deixa de ser uma falha. Em uma réplica uma morte OOM, uma sonda de vida falhada ou um dreno de nó levou tudo para baixo para O tempo que for preciso para arrancar. topologiaSpreadConstraints (adicionado mais cedo, inerte até agora) manter os dois em nós diferentes onde o cluster pode gerenciá-lo, e um PodDisruptionBudget no KlusterServices faz um dreno esperar.

  18. · kamo-nowww

    Drene no SIGTERM, e responda a uma sonda de prontidão

    Em seguida, lida com o SIGTERM com um process.exit nu(143), então cada implantação cortou o que quer que este pod tinha em vôo — uma postagem de formulário, uma ação do servidor, uma carga útil RSC transmitida, um upload. Invisível quando uma a requisição durou milissegundos; não invisível em um cluster que é implantado em cada push. scripts/standalone-entry.cjs envolve o servidor standalone: no SIGTERM ele pára de aceitar, deixa inativo manter-vivos de uma vez para que uma cápsula sem nada em vôo ainda sai em cerca de um segundo, e vamos correr Os pedidos terminam sob uma tampa que fica abaixo da terminaçãoGracePeriodSeconds. Portados de Kamo-internal, que a tem executado em produção há meses. Esta implantação não tinha nenhuma sonda de prontidão, então uma cápsula contada como Pronto no instante em que o seu recipiente processo iniciado. Com maxIndisponível 0 Kubernetes lê que como "o novo pod está servindo" e retira-se o antigo — enquanto o Next ainda está a inicializar e não ligou o seu porto. Pedidos desembarcados em um porto nada estava ouvindo em, que é de onde os 502s intermitentes em implantação vieram. /api/saúde responde apenas para esta cápsula e deliberadamente não toca nenhuma infra-estrutura: uma sonda de prontidão decide se este pod deixa o Serviço, e fiação para uma infra- estrutura transforma um blip de infra- estrutura em uma A reiniciar cada cápsula aqui. Já em duas réplicas; isto é o que faz o segundo realmente cobrir o primeiro durante um rollout em vez de ambos serem substituídos cegos.

  19. · kamo-shared-library

    Uma fechadura distribuída, para que uma varredura programada possa sobreviver a uma segunda réplica

    Não há nenhum ShedLock em qualquer lugar nesta plataforma e nunca houve. Todos os 97 @Scheduled varreduras em 18 serviços estão corretas apenas porque cada serviço funciona exatamente uma cápsula. Escalar eles e a varredura são executados duas vezes por tique — dois lembretes de reunião na caixa de entrada de um membro, dois chat-email avisos, dois passes sobre um período de faturamento. Esses destacamentos uni-replica não foram apenas não escalado; a contagem de réplicas foi rolamento de carga, e o código diz isso em três lugares já. * * ********** *lease, corpo) dirige um corpo em exatamente uma cápsula. Uma chamada explícita, não uma anotação. @SingletonTask ao lado de @Scheduled é o design óbvio e ele é uma armadilha aqui: seria aplicada por um proxy de AOP, e um proxy é completamente contornado quando um método é alcançado de dentro do mesmo feijão — o problema da auto-invocação da Primavera esta base de código foi Apanhado por cinco vezes diferentes. Uma varredura que silenciosamente perdeu sua fechadura e correu em cada cápsula é que o mesmo fracasso, e nada o revelaria até que um cliente contasse seus e-mails. Levando a fechadura chamando-o não pode ser contornado por como o método foi alcançado, e ele greps. REDIS, não a base de dados. Uma tabela de bloqueio precisa de DDL, e DDL neste cluster faz cada resposta de serviço 500 'schema versão mismatch' por ~15 minutos enquanto as conexões Hikari envelhecem. Pagar a falha de plataforma para instalar a maquinaria que impede interrupções de plataforma é um mau comércio quando o Redis já está implantado. Falhas fechadas. Se o Redis não for acessível, a tarefa será ignorada, não executada: para o trabalho que envia e- mail ou move dinheiro, correr duas vezes é pior do que não correr, e o próximo tique-taque repete. Release é uma programa de comparação-e-delete para que um corpo que overran sua locação não pode excluir um bloqueio outro pod tem desde tomada, e invadindo é registrado no ERROR porque nada mais iria revelá-lo. Onde um serviço não tem o Redis, o backback corre o corpo sempre — exatamente o que o código faz hoje, assim, adotar isso nunca muda de comportamento por si só — e avisa na inicialização. A guarda manifesta em CI recusa réplicas > 1 para um serviço nesse estado. 7 testes; suite completa 2710 verde.

  20. · kamo-register

    Pinte cada logotipo no local de inscrição na cor de sobreposição da org

    O org escolhe "Registrar Logotipo do Site Sobreposição" em kamo-internal ao lado do Página inicial e sobreposições da tela de carregamento. Uma configuração para todo o site: cada etapa do fluxo de registro, da organização e das telas de equipe, a tela de conclusão e a tela de assinatura fechada. Assim, ThemeLogo não toma nenhum prop para ele e lê a cor em si, a maneira como ele já lê a empresa-vs-software identidade logo - config.json é este site é a única fonte de branding org, e um prop seria mais um coisa que cada site de chamadas tem que lembrar. A cor já chega resolvida: kamo-internal armazena um TOKEN org que rebrands mantém uma sobreposição correspondente, e o serviço de segurança resolve contra a paleta daquela org quando escreve config.json. Nada aqui. precisa do vocabulário de treze token. Um valor CSS não pode processar é descartado em vez de passar - uma cor de fundo inválida pinta o mascarado caixa transparente, que lê como um logotipo que desapareceu. Uma máscara, não um filtro: um filtro só pode empurrar as cores existentes de um logotipo em torno e não consegue alcançar um alvo arbitrário. O <img> permanece montado e Apenas invisível para que continue a segurar a sua caixa exacta para a máscara preencher, Deixando todos os layouts de chamadas inalterados. Sua própria coluna e sua própria chave config.json, separadas do sign-in site's: os dois são marcados de forma independente, e uma org que uma não necessita de marcação branca na outra.

  21. · kamo-login

    Pinte cada logotipo no local de entrada na cor de sobreposição do org

    O org escolhe "Login Site Logo Overlay" em kamo-internal ao lado da casa sobreposições de tela de página e carregamento. Uma configuração para todo o site: o sign-in form, o coletor de espaço de trabalho, recuperação de senha e reset, e o tela de saída são o mesmo logotipo no mesmo fundo, e ninguém quer para definir a sombra cinco vezes. Assim, ThemeLogo não toma nenhum prop para ele e lê a cor em si, a maneira como ele já lê a empresa-vs-software identidade logo - config.json é este site é a única fonte de branding org, e um prop seria mais um coisa que cada site de chamadas tem que lembrar. A cor já chega resolvida: kamo-internal armazena um TOKEN org que rebrands mantém uma sobreposição correspondente, e o serviço de segurança resolve contra a paleta daquela org quando escreve config.json. Nada aqui. precisa do vocabulário de treze token. Um valor CSS não pode processar é descartado em vez de passar - uma cor de fundo inválida pinta o mascarado caixa transparente, que lê como um logotipo que desapareceu. Uma máscara, não um filtro: um filtro só pode empurrar as cores existentes de um logotipo em torno e não consegue alcançar um alvo arbitrário. O <img> permanece montado e apenas invisível para que ainda dispara em Load (a única fonte de naturalSize) e sobreErro (que caminha o logo-full extensão fallbacks), e assim ele Ainda tem a sua caixa exacta para a máscara preencher. Cada disposição de chamada é inalterado. A pequena marca animada na pílula "Desenvolvido por KamoCRM" é o próprio org logo também, por isso segue a configuração - ele apenas renderiza através da próxima / imagem para a carga ansiosa da pílula, por isso carrega a máscara em si em vez de tornando-se um ThemeLogo. De outra forma, teria sido o único logótipo na local a configuração falhou.

  22. · kamo-internal

    Escolha uma sobreposição de logotipo para os sites de entrada e inscrição

    Uma quarta e quinta superfície ao lado da página inicial, tela de carregamento e KamoMeets sobrepõe, compartilhando seu vocabulário de treze token e suas vidas Swatches. Ambos são sempre oferecidos, ao contrário do KamoMeets um: cada org tem uma entrada e um site de inscrição quaisquer aplicativos que ele executar, e uma org sem domínio de sua próprio ainda os atinge no login./register.kamocrm.com pintado em seu próprio Marcas. Eles também são as únicas duas sobreposições aqui que não se aplicam no momento em que eles estão salvos. kamo-login e kamo-register não têm OrgContext para ler, então o serviço de segurança resolve o token e ajusta a cor no tema config.json esses sites obtêm; a mudança de terras ao fornecer reescreve esse arquivo, que o mesmo salvar já dispara. Cinco dropdowns quase idênticos teriam sido cinco lugares para derivar, então o editor block é agora um renderOverlaySelect() o compartilhamento de superfícies - um sexto superfície é uma chamada em vez de outras vinte linhas. As linhas somente de leitura já compartilhou deles. Os dois campos montam a Organização. de JSON como seus irmãos, com um teste de ida e volta: o mapper roda duas vezes no caminho para o navegador, e um campo que ele não pode ler de volta de sua própria saída é uma configuração que silenciosamente reverte na sua próxima carga.

  23. · MediaService

    Faça o MediaService correto em mais de um pod e execute dois

    MediaService só executou uma única réplica, então uma implantação dela foi um total bate-papo e Um OOM era o mesmo. Não foi possível executar dois, por razões que estavam todas no código: 1. O stomp broker está no coração. habilitarSimpleBroker significa converterAndSend atinge apenas o WebSockets ligado à cápsula a fazer a chamada. Treze controladores de relé já lidaram com isso corretamente assinando o NATS com um expedidor simples (sem grupo de fila, então cada pod recebe cada mensagem) e re-publicando localmente. Treze outros sítios de chamadas não — indicadores de tipografia, presença, emblemas não lidos, subsídios de resposta, oferta/resposta/ICE WebRTC, notificações de bate-papo recebidas – e cada um teria entregue à metade da audiência pretendida. StompFanout generaliza o padrão que os relés já usam: publicar {destino, carga} em Um assunto central da NATS, cada cápsula retransmite para o seu próprio corretor. Core NATS, não JetStream, porque estes são eventos de momento ao vivo sem valor reproduzido e sem fluxo cobrindo o assunto. Como o núcleo NATS também entrega ao editor, send() NÃO escreve localmente também — que Entregaria duas vezes aqui. Com NATS para baixo ele cai de volta a um envio local, que é o que o A plataforma já o fez antes. 2. O consumidor por conversação era um durável exclusivo. ChatSessionSubscriptionManager nomeou seu JetStream durável após a sessão de chat GUID, e um consumidor de push durável admite exatamente um assinante. A ligação da segunda cápsula foi recusada [SUB-90012] e cada membro cuja tomada pousou não recebeu nada — nenhuma mensagem, nenhum recibo de leitura, nenhum evento associado, nenhum erro. Agora um consumidor efêmero: nenhum nome para colidir, um por pod, colhido pelo servidor. A repetição desta remoção inventou um novo nome durável na colisão. Funcionou, e vazou um consumidor permanente do lado do servidor por colisão que nada apagou. 3. 5 MAIS FIXED-NAME DURÁVEIS, necessitando de tratamento oposto dependendo do trabalho. A conversão e os relés STOMP VOIP passaram pelo JetStream em vez de um despachante de núcleo, então eles tinham o mesmo bug de exclusividade — agora efêmero, já que cada vagem deve receber. O notificador de chat-email, social o consumidor de conversão de consumo e de comercialização deve funcionar exactamente uma vez, de modo a manter a sua duráveis e junte-se a um grupo de entrega, o que também significa que um sobrevivente pega o trabalho quando uma cápsula morre. Sessões fixas na rota de mídia são necessárias, não opcional: estes clientes STOMP usam SockJS, cujo backback xhr-streaming/xhr-polling é várias solicitações HTTP para uma conexão contra o estado de sessão que vive na memória de uma cápsula. O Round-Robin parte-o. Ver entradaroute.yaml. réplicas 1 -> 2. 367 testes passam.

  24. · SecurityService

    Asse as sobreposições de logo de entrada e inscrição em config.json

    kamo-login e kamo-register executados em suas próprias máquinas sem OrgContext, então este arquivo é a única rota que sua marca toma - o mesmo KamoMeet já usa. O token é resolvido contra a paleta do org AQUI e o Hex finalizado é escrito, o que mantém o vocabulário de treze token fora de Mais duas bases de código que cada um precisaria de sua própria cópia. Cozer uma cor resolvida não é o erro que o token armazenado evita: isto arquivo é regenerado em cada gravação de marca, mudanças de cor incluídas, então o valor não pode ficar obsoleto. Ausente significa sem sobreposição, então uma org que não tenha escolhido nenhum ganha nenhuma chave e seu logos render intocado - que é cada org até que um é escolhido. Os testes cobrem as três superfícies que se mantêm separadas: partilham um construtor e um org sobrepondo seu site de entrada não deve ter seu logotipo KamoMeet pintado como efeito secundário.

  25. · kamo-shared-library

    Sobreposição de logotipo para os sites de entrada e inscrição

    Mais duas colunas no vocabulário home logo overlay já estabelecido: um token, não um hex, assim que uma org que rebrands mantém uma sobreposição combinando sua novas cores. Ambos nulláveis sem backfill - null é NONE, que é o que Todas as orgias se parecem com hoje. Separar colunas em vez de uma configuração partilhada, pela mesma razão home page e tela de carregamento têm seus próprios: os dois sites são marcados independentemente, e uma org que os rótulos brancos não necessitam de rótulo branco o outro. patchOrganização é um ALLOW-LIST, então os nomes vão lá também. Uma coluna este serviço feliz desserializes mas esse método não nome é aceito com um 200 e silenciosamente nunca armazenado - nenhum erro, nenhuma linha de log, e o único sintoma é uma configuração que reverte em sua próxima carga.

  26. · kamo-login

    Responder ao link em uma carta de mudança de endereço

    /verify-email-change gasta o token em uma carta de mudança de endereço e diz O que aconteceu. Vive aqui em vez de no espaço de trabalho porque a carta vai a uma caixa de correio PESSOAL — geralmente lido num telefone que nunca assinou o espaço de trabalho, e muitas vezes não assinou em nada. login.<domínio> é o único host que sempre resolve para uma organização e nunca precisa de uma sessão, é o único lugar onde o link é certo para trabalhar para a pessoa que mais precisa dele. Nada na página pede nada. Chega, gasta o símbolo, e Relatórios — um formulário aqui seria um formulário que o leitor não pode preencher do Eles abriram a caixa de correio. O gasto é guardado contra o desenvolvimento do React duplo-invoque, porque o token é de uso único e uma segunda chamada iria gastá-lo e então relatar o sucesso como "este link não é mais válido". O relé ao lado /api/recuperar e moldado da mesma forma: ClusterIP-somente, então ele vai sobre o cluster DNS, o que faz Hospede o nome do serviço e coloca o nome da máquina do navegador no X- Forwarded-Host — o único cabeçalho do A infra- estrutura lê- a.

  27. · kamo-internal

    Altere seu próprio endereço e uma guia de plataforma para cada conta

    Duas superfícies, unidas por uma distinção, a plataforma nunca explicou qualquer pessoa: uma conta de usuário é a PESSOA, e um membro é de uma organização relação com essa pessoa. Meu perfil ganha um cartão de e-mail pessoal, na sala de acesso ao lado do senha porque é isso que é — um dos três identificadores aceita, e o endereço para o qual uma senha reset é enviada. Arquivar sob contacto Os detalhes seriam arquivar uma chave sob papelaria. Compromete-se em vez de passando pela barra de salvamento da sala: uma mudança é um pedido, uma carta e um confirmação, e um botão Salvar que escreveu um identificador de login sem prova a caixa de correio existe seria todo o problema em um controle. A conta pertence à organização nomeada por security provider id, e apenas Isso pode mudar. O cartão é, portanto, visível em todos os lugares e editável em um lugar — escondê-lo nos outros deixaria um membro à procura de um cenário que parece ter sido suprimida. Onde não pode ser editado diz de quem é é, e oferece ambos os caminhos de volta: mudando do menu superior esquerdo sem sair o aplicativo, e assinando diretamente no endereço de entrada da própria organização (ou, quando ainda não tem nenhum, no compartilhado, nomeado como tal). Ambos vêm de OrgEntryDomainResolver, então o host nunca é aquele que deixa de resolver. Um explicador senta-se sob o cartão em cada organização, não só dentro do Recusa. "Conta de usuário" versus "conta de membro" é uma distinção ninguém fora a plataforma tem qualquer razão para saber, e torna-se suporte de carga em exatamente o momento alguém é recusado algo — que é o pior momento possível para encontrar uma ideia pela primeira vez. /conta ganha uma quarta aba, Usuários, fechado na nova plataforma MANAGEM USERS Certo. O direito já carrega a "organização atual deve ser a plataforma organização" pré-condição — PlatformRightsResolver não devolve nada a um sessão dentro de um inquilino — para que a aba não verifique a organização separadamente; uma segunda autoridade lá só poderia discordar do servidor. Pesquisar e paging também são do servidor: o próprio filtro da grade pesquisa as linhas que acontece para manter, que em uma tabela de plataforma significa reportar "sem resultados" para uma conta que existe. A gaveta atrás de uma fileira é marcada por consequência, em vez de por tópico. Identidade edita em um rascunho e salva uma vez; o estado da conta commits por switch e relatórios quantas sessões foram com ele; recuperação é definida e confirmada. Deus. contas e o usuário do sistema renderizar somente leitura, porque o servidor as recusa e compor uma edição que nunca iria pousar é pior do que ser dito Primeiro. Também corrige o banner provedor de segurança que esteve nesta página o tempo todo. Ele construiu seu link de `org.domain` mais ID de membro desta organização — um nome da máquina que não é a máquina do espaço de trabalho, num ID de membro que não existe sobre Pronto. Agora aponta para a tela de entrada que o servidor resolve.

  28. · kamo-shared-library

    Adicionar um subscritor de grupo de fila, por isso o trabalho é partilhado em vez de fixado a um pod

    Companheiro para subscrever o Efêmero. Dois empregos diferentes, dois consumidores diferentes: cada pod deve ver cada mensagem (qualquer coisa que termine em uma transmissão STOMP) subscrevaO trabalho deve acontecer exatamente ONCE (enviar um e-mail, chamando um provedor) Nem é o que uma simples durável faz em mais de uma réplica. Sem entregar grupo um empurrão durável consumidor admite um único assinante, por isso o segundo pod é recusado [SUB-90012] e o trabalho é preso a qualquer cápsula ligada primeiro — sem nada assumir se essa é a cápsula que morre. Adicionar um grupo de entrega torna o mesmo durável em uma fila o compartilhamento de pods, mantendo redelivery e MaxDeliver exactamente como estavam. reconciliarDeliverGroup espelha o conciliar existenteDurableFilter, e não é opcional: cada consumidor esta mudança converte já existe no fluxo na forma antiga, e jnats não Junte-se a uma linha durável. Sem a reconciliação, o primeiro destacamento depois disso iria deixar as assinaturas permanentemente mortas em vez de partilhadas — o mesmo fracasso silencioso e perpetuante o filtro de reconciliação foi escrito para. O laço de entrega é agora um método por trás dos três pontos de entrada.

  29. · kamo-shared-library

    Adicione uma assinatura efêmera, para que mais de um pod possa servir uma conversa

    Um consumidor de empurrão durável admite exatamente um assinante. A segunda cápsula a ligar o mesmo nome é recusada com [SUB-90012] O consumidor já está vinculado a uma subscrição, e nada repete. ChatSessionSubscriptionManager nomeia seu durável após a sessão de chat GUID, então com dois Os pods do MediaService, qualquer que fosse a primeira conversação, silenciosamente a possuiria e a cada membro cujo WebSocket pousou na outra cápsula não receberia nada — sem mensagens, sem recibos de leitura, não eventos associados, sem erros. Essa única propriedade é porque MediaService foi presa a um réplica, e por que uma implantação dele é uma interrupção total do chat em vez de uma capotagem. subscreveEphemeral () cria um consumidor sem nome. Não há nenhuma identidade de cross-pod para colidir Assim, cada pod recebe cada mensagem e fãs para seus próprios clientes STOMP — que é o o simples corretor requer. Mantém o filtroSujeite o caminho durável aprendido a definir (um filtro vazio consome todo o fluxo), e adiciona um limiar inativo para um pod que é SIGKILLed sem que o cancelamento não deixe o seu consumidor na corrente para sempre. Nenhuma alteração de comportamento para chamadas existentes: subscribe() é intocada, e o loop de entrega ambos o uso de caminhos é agora um método para que eles não possam derivar. Os consumidores efémeros não reproduzem mensagens publicadas enquanto nada foi subscrito. Nem o duráveis — ambos usam a DeliverPolítica. Novo — portanto isto não é uma regressão.

  30. · kamo-internal

    "O que aconteceu?" enche a janela, assim maximizando amplia-a

    Todos os outros campos do formulário de relatório são dimensionados pelo seu conteúdo. A descrição é o que alguém está realmente escrevendo, então agora leva qualquer altura que resta — e maximizar a janela da ferramenta é, portanto Vale a pena fazer isso. Três partes, e todas as três são necessárias: A área de rolagem ganha uma coluna flex interna em `minHeight: 100%`, não «Altura: 100%». A uma altura total fixa uma forma mais alta do que a janela iria comprimir seus próprios campos, porque flex crianças encolhem por padrão. No mínimo, é exatamente altura total quando há espaço para sobrar — que é o quarto que a descrição toma — e cresce além dele quando há Não, em que ponto a caixa exterior rola e nada é esmagado. O campo torna-se um item flexível com um piso 'minHeight'. "minRows" foi-se. com ele: que impulsiona TextareaAutosize, que mede o conteúdo e escreve uma altura em linha, e com `flex-base: 0` haveria de outra forma Nada que impeça o colapso do campo a zero. A área de texto é lançada com `altura: auto!importante`, NÃO «Altura: 100%». A embalagem esboçada estende seus filhos, de modo que o textarea iria preenchê-lo sem ajuda — exceto um item flex com uma definição cross-size não esticar, e autosize dá-lhe um em linha. Configuração altura de volta para auto restaura o trecho em vez de lutar contra ele. 100% foi tentou primeiro e silenciosamente nada faz: a percentagem não tem definitivo contendo bloco para resolver contra, então ele cai de volta para auto e o campo renderiza em suas duas linhas intrínsecas, sem nenhum erro em qualquer lugar para reparar. Medida, não presumida. Um arnês de marionetista construído a partir deste componente saída própria emoção dá 240px de textarea em uma janela 720px, 444px em 940px, e um campo com pisos com o formulário rolagem em 430px — com o campo título ainda 40px em todos os três. A guarda empenhada afirma que regra em vez da altura, uma vez que jsdom não faz nenhum layout, e foi Confirmada a falha quando a regra é revertida para 100%.

Seu universo está esperando.

Comece gratuitamente em minutos.Adicione produtos sempre que estiver pronto — sem migração, sem novos logins.

Gratuito para sempre — não é necessário cartão de crédito