Native CLI i18n: The TrustGraph CLI has built-in translation support that dynamically loads language strings. You can test and use different languages by simply passing the --lang flag (e.g., --lang es for Spanish, --lang ru for Russian) or by configuring your environment's LANG variable. Automated Docs Translations: This PR introduces autonomously translated Markdown documentation into several target languages, including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew, Arabic, Simplified Chinese, and Russian.
31 KiB
| layout | title | parent |
|---|---|---|
| default | Especificação Técnica: Suporte para Multi-Tenancy | Portuguese (Beta) |
Especificação Técnica: Suporte para Multi-Tenancy
Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
Visão Geral
Habilite implantações multi-tenant corrigindo incompatibilidades de nomes de parâmetros que impedem a personalização da fila e adicionando parametrização do keyspace do Cassandra.
Contexto da Arquitetura
Resolução de Filas Baseada em Fluxo
O sistema TrustGraph usa uma arquitetura baseada em fluxo para a resolução dinâmica de filas, que suporta inerentemente o multi-tenancy:
As Definições de Fluxo são armazenadas no Cassandra e especificam os nomes das filas por meio de definições de interface.
Os nomes das filas usam modelos com variáveis {id} que são substituídas pelos IDs das instâncias de fluxo.
Os serviços resolvem dinamicamente as filas consultando as configurações de fluxo no momento da solicitação.
Cada tenant pode ter fluxos únicos com nomes de fila diferentes, proporcionando isolamento.
Exemplo de definição de interface de fluxo:
{
"interfaces": {
"triples-store": "persistent://tg/flow/triples-store:{id}",
"graph-embeddings-store": "persistent://tg/flow/graph-embeddings-store:{id}"
}
}
Quando o tenant A inicia o fluxo tenant-a-prod e o tenant B inicia o fluxo tenant-b-prod, eles automaticamente recebem filas isoladas:
persistent://tg/flow/triples-store:tenant-a-prod
persistent://tg/flow/triples-store:tenant-b-prod
Serviços corretamente projetados para multi-tenancy: ✅ Knowledge Management (cores) - Resolve dinamicamente as filas a partir da configuração do fluxo passada nas requisições
Serviços que precisam de correções: 🔴 Config Service - Incompatibilidade no nome do parâmetro impede a personalização da fila 🔴 Librarian Service - Tópicos de gerenciamento de armazenamento codificados (discutido abaixo) 🔴 Todos os Serviços - Não é possível personalizar o keyspace do Cassandra
Declaração do Problema
Problema #1: Incompatibilidade no Nome do Parâmetro no AsyncProcessor
CLI define: --config-queue (nomeação pouco clara)
Argparse converte para: config_queue (no dicionário de parâmetros)
Código procura por: config_push_queue
Resultado: O parâmetro é ignorado, usa o valor padrão de persistent://tg/config/config
Impacto: Afeta todos os 32+ serviços que herdam do AsyncProcessor
Bloqueia: Impossibilita o uso de filas de configuração específicas do tenant em implantações multi-tenant
Solução: Renomear o parâmetro da CLI para --config-push-queue para maior clareza (alteração disruptiva aceitável, já que o recurso está atualmente com defeito)
Problema #2: Incompatibilidade no Nome do Parâmetro no Config Service
CLI define: --push-queue (nomeação ambígua)
Argparse converte para: push_queue (no dicionário de parâmetros)
Código procura por: config_push_queue
Resultado: O parâmetro é ignorado
Impacto: O Config service não pode usar uma fila de push personalizada
Solução: Renomear o parâmetro da CLI para --config-push-queue para consistência e clareza (alteração disruptiva aceitável)
Problema #3: Keyspace do Cassandra Codificado
Atual: Keyspace codificado como "config", "knowledge", "librarian" em vários serviços
Resultado: Impossibilita a personalização do keyspace para implantações multi-tenant
Impacto: Serviços Config, cores e librarian
Bloqueia: Múltiplos tenants não podem usar keyspaces separados do Cassandra
Problema #4: Arquitetura de Gerenciamento de Coleções ✅ CONCLUÍDO
Anterior: Coleções armazenadas no keyspace do librarian do Cassandra em uma tabela de coleções separada
Anterior: O librarian usava 4 tópicos de gerenciamento de armazenamento codificados para coordenar a criação/exclusão de coleções:
vector_storage_management_topic
object_storage_management_topic
triples_storage_management_topic
storage_management_response_topic
Problemas (Resolvidos):
Tópicos codificados não podiam ser personalizados para implantações multi-tenant
Coordenação assíncrona complexa entre o librarian e 4+ serviços de armazenamento
Tabela separada do Cassandra e infraestrutura de gerenciamento
Filas de requisição/resposta não persistentes para operações críticas
Solução Implementada: Migrou as coleções para o armazenamento do serviço de configuração, usa push de configuração para distribuição
Status: Todos os backends de armazenamento migrados para o padrão CollectionConfigHandler
Solução
Esta especificação aborda os problemas #1, #2, #3 e #4.
Parte 1: Corrigir Incompatibilidades no Nome do Parâmetro
Alteração 1: Classe Base AsyncProcessor - Renomear Parâmetro da CLI
Arquivo: trustgraph-base/trustgraph/base/async_processor.py
Linha: 260-264
Atual:
parser.add_argument(
'--config-queue',
default=default_config_queue,
help=f'Config push queue {default_config_queue}',
)
Corrigido:
parser.add_argument(
'--config-push-queue',
default=default_config_queue,
help=f'Config push queue (default: {default_config_queue})',
)
Justificativa:
Nomenclatura mais clara e explícita
Coincide com o nome da variável interna config_push_queue
Mudança disruptiva aceitável, já que a funcionalidade está atualmente inativa
Não é necessária nenhuma alteração no código em params.get() - ele já procura pelo nome correto
Mudança 2: Serviço de Configuração - Renomear Parâmetro da CLI
Arquivo: trustgraph-flow/trustgraph/config/service/service.py
Linha: 276-279
Atual:
parser.add_argument(
'--push-queue',
default=default_config_push_queue,
help=f'Config push queue (default: {default_config_push_queue})'
)
Corrigido:
parser.add_argument(
'--config-push-queue',
default=default_config_push_queue,
help=f'Config push queue (default: {default_config_push_queue})'
)
Justificativa:
Nomes mais claros - "config-push-queue" é mais explícito do que apenas "push-queue".
Compatível com o nome da variável interna config_push_queue.
Consistente com o parâmetro --config-push-queue do AsyncProcessor.
Mudança disruptiva aceitável, já que o recurso está atualmente inativo.
Nenhuma alteração de código necessária em params.get() - ele já procura pelo nome correto.
Parte 2: Adicionar Parametrização do Keyspace do Cassandra
Mudança 3: Adicionar Parâmetro de Keyspace ao Módulo cassandra_config
Arquivo: trustgraph-base/trustgraph/base/cassandra_config.py
Adicionar argumento de linha de comando (na função add_cassandra_args()):
parser.add_argument(
'--cassandra-keyspace',
default=None,
help='Cassandra keyspace (default: service-specific)'
)
Adicionar suporte para variáveis de ambiente (na função resolve_cassandra_config()):
keyspace = params.get(
"cassandra_keyspace",
os.environ.get("CASSANDRA_KEYSPACE")
)
Atualizar o valor de retorno de resolve_cassandra_config():
Atualmente retorna: (hosts, username, password)
Alterar para retornar: (hosts, username, password, keyspace)
Justificativa:
Consistente com o padrão de configuração existente do Cassandra
Disponível para todos os serviços via add_cassandra_args()
Suporta configuração via linha de comando e variáveis de ambiente
Mudança 4: Serviço de Configuração - Usar Keyspace Parametrizados
Arquivo: trustgraph-flow/trustgraph/config/service/service.py
Linha 30 - Remover o keyspace codificado:
# DELETE THIS LINE:
keyspace = "config"
Linhas 69-73 - Atualização da resolução da configuração do Cassandra:
Atual:
cassandra_host, cassandra_username, cassandra_password = \
resolve_cassandra_config(params)
Corrigido:
cassandra_host, cassandra_username, cassandra_password, keyspace = \
resolve_cassandra_config(params, default_keyspace="config")
Justificativa:
Mantém a compatibilidade com versões anteriores, utilizando "config" como padrão.
Permite a substituição através de --cassandra-keyspace ou CASSANDRA_KEYSPACE.
Mudança 5: Cores/Serviço de Conhecimento - Utilizar Chaves de Espaço de Chaves Parametrizadas
Arquivo: trustgraph-flow/trustgraph/cores/service.py
Linha 37 - Remover o espaço de chaves codificado:
# DELETE THIS LINE:
keyspace = "knowledge"
Atualização da resolução de configuração do Cassandra (localização semelhante ao serviço de configuração):
cassandra_host, cassandra_username, cassandra_password, keyspace = \
resolve_cassandra_config(params, default_keyspace="knowledge")
Mudança 6: Serviço de Bibliotecário - Use Chaves de Espaço de Chaves Parametrizadas
Arquivo: trustgraph-flow/trustgraph/librarian/service.py
Linha 51 - Remova a chave de espaço de chaves codificada:
# DELETE THIS LINE:
keyspace = "librarian"
Atualização da resolução de configuração do Cassandra (localização semelhante ao serviço de configuração):
cassandra_host, cassandra_username, cassandra_password, keyspace = \
resolve_cassandra_config(params, default_keyspace="librarian")
Parte 3: Migrar o Gerenciamento de Coleções para o Serviço de Configuração
Visão Geral
Migrar as coleções do keyspace do Cassandra librarian para o armazenamento do serviço de configuração. Isso elimina os tópicos de gerenciamento de armazenamento codificados e simplifica a arquitetura, utilizando o mecanismo de push de configuração existente para distribuição.
Arquitetura Atual
API Request → Gateway → Librarian Service
↓
CollectionManager
↓
Cassandra Collections Table (librarian keyspace)
↓
Broadcast to 4 Storage Management Topics (hardcoded)
↓
Wait for 4+ Storage Service Responses
↓
Response to Gateway
Nova Arquitetura
API Request → Gateway → Librarian Service
↓
CollectionManager
↓
Config Service API (put/delete/getvalues)
↓
Cassandra Config Table (class='collections', key='user:collection')
↓
Config Push (to all subscribers on config-push-queue)
↓
All Storage Services receive config update independently
Mudança 7: Gerenciador de Coleções - Usar API do Serviço de Configuração
Arquivo: trustgraph-flow/trustgraph/librarian/collection_manager.py
Remover:
Uso de LibraryTableStore (Linhas 33, 40-41)
Inicialização de produtores de gerenciamento de armazenamento (Linhas 86-140)
Método on_storage_response (Linhas 400-430)
Rastreamento de pending_deletions (Linhas 57, 90-96 e uso em todo o código)
Adicionar: Cliente do serviço de configuração para chamadas de API (padrão de solicitação/resposta)
Configuração do Cliente:
# In __init__, add config request/response producers/consumers
from trustgraph.schema.services.config import ConfigRequest, ConfigResponse
# Producer for config requests
self.config_request_producer = Producer(
client=pulsar_client,
topic=config_request_queue,
schema=ConfigRequest,
)
# Consumer for config responses (with correlation ID)
self.config_response_consumer = Consumer(
taskgroup=taskgroup,
client=pulsar_client,
flow=None,
topic=config_response_queue,
subscriber=f"{id}-config",
schema=ConfigResponse,
handler=self.on_config_response,
)
# Tracking for pending config requests
self.pending_config_requests = {} # request_id -> asyncio.Event
Modificar list_collections (Linhas 145-180):
async def list_collections(self, user, tag_filter=None, limit=None):
"""List collections from config service"""
# Send getvalues request to config service
request = ConfigRequest(
id=str(uuid.uuid4()),
operation='getvalues',
type='collections',
)
# Send request and wait for response
response = await self.send_config_request(request)
# Parse collections from response
collections = []
for key, value_json in response.values.items():
if ":" in key:
coll_user, collection = key.split(":", 1)
if coll_user == user:
metadata = json.loads(value_json)
collections.append(CollectionMetadata(**metadata))
# Apply tag filtering in-memory (as before)
if tag_filter:
collections = [c for c in collections if any(tag in c.tags for tag in tag_filter)]
# Apply limit
if limit:
collections = collections[:limit]
return collections
async def send_config_request(self, request):
"""Send config request and wait for response"""
event = asyncio.Event()
self.pending_config_requests[request.id] = event
await self.config_request_producer.send(request)
await event.wait()
return self.pending_config_requests.pop(request.id + "_response")
async def on_config_response(self, message, consumer, flow):
"""Handle config response"""
response = message.value()
if response.id in self.pending_config_requests:
self.pending_config_requests[response.id + "_response"] = response
self.pending_config_requests[response.id].set()
Modificar update_collection (Linhas 182-312):
async def update_collection(self, user, collection, name, description, tags):
"""Update collection via config service"""
# Create metadata
metadata = CollectionMetadata(
user=user,
collection=collection,
name=name,
description=description,
tags=tags,
)
# Send put request to config service
request = ConfigRequest(
id=str(uuid.uuid4()),
operation='put',
type='collections',
key=f'{user}:{collection}',
value=json.dumps(metadata.to_dict()),
)
response = await self.send_config_request(request)
if response.error:
raise RuntimeError(f"Config update failed: {response.error.message}")
# Config service will trigger config push automatically
# Storage services will receive update and create collections
Modificar delete_collection (Linhas 314-398):
async def delete_collection(self, user, collection):
"""Delete collection via config service"""
# Send delete request to config service
request = ConfigRequest(
id=str(uuid.uuid4()),
operation='delete',
type='collections',
key=f'{user}:{collection}',
)
response = await self.send_config_request(request)
if response.error:
raise RuntimeError(f"Config delete failed: {response.error.message}")
# Config service will trigger config push automatically
# Storage services will receive update and delete collections
Formato de Metadados de Coleção:
Armazenado na tabela de configuração como: class='collections', key='user:collection'
O valor é uma CollectionMetadata serializada em JSON (sem campos de timestamp)
Campos: user, collection, name, description, tags
Exemplo: class='collections', key='alice:my-docs', value='{"user":"alice","collection":"my-docs","name":"My Documents","description":"...","tags":["work"]}'
Mudança 8: Serviço de Bibliotecário - Remover a Infraestrutura de Gerenciamento de Armazenamento
Arquivo: trustgraph-flow/trustgraph/librarian/service.py
Remover:
Produtores de gerenciamento de armazenamento (Linhas 173-190):
vector_storage_management_producer
object_storage_management_producer
triples_storage_management_producer
Consumidor de resposta de armazenamento (Linhas 192-201)
Manipulador on_storage_response (Linhas 467-473)
Modificar: Inicialização do CollectionManager (Linhas 215-224) - remover os parâmetros do produtor de armazenamento
Observação: A API externa de coleções permanece inalterada:
list-collections
update-collection
delete-collection
Mudança 9: Remover a Tabela de Coleções do LibraryTableStore
Arquivo: trustgraph-flow/trustgraph/tables/library.py
Excluir:
Instrução CREATE da tabela de coleções (Linhas 114-127)
Prepared statements de coleções (Linhas 205-240)
Todos os métodos de coleção (Linhas 578-717):
ensure_collection_exists
list_collections
update_collection
delete_collection
get_collection
create_collection
Justificativa: As coleções agora são armazenadas na tabela de configuração Mudança disruptiva aceitável - nenhuma migração de dados necessária Simplifica significativamente o serviço de bibliotecário
Mudança 10: Serviços de Armazenamento - Gerenciamento de Coleção Baseado em Configuração ✅ CONCLUÍDO
Status: Todos os 11 backends de armazenamento foram migrados para usar CollectionConfigHandler.
Serviços Afetados (11 no total): Embeddings de documentos: milvus, pinecone, qdrant Embeddings de grafos: milvus, pinecone, qdrant Armazenamento de objetos: cassandra Armazenamento de triplas: cassandra, falkordb, memgraph, neo4j
Arquivos:
trustgraph-flow/trustgraph/storage/doc_embeddings/milvus/write.py
trustgraph-flow/trustgraph/storage/doc_embeddings/pinecone/write.py
trustgraph-flow/trustgraph/storage/doc_embeddings/qdrant/write.py
trustgraph-flow/trustgraph/storage/graph_embeddings/milvus/write.py
trustgraph-flow/trustgraph/storage/graph_embeddings/pinecone/write.py
trustgraph-flow/trustgraph/storage/graph_embeddings/qdrant/write.py
trustgraph-flow/trustgraph/storage/objects/cassandra/write.py
trustgraph-flow/trustgraph/storage/triples/cassandra/write.py
trustgraph-flow/trustgraph/storage/triples/falkordb/write.py
trustgraph-flow/trustgraph/storage/triples/memgraph/write.py
trustgraph-flow/trustgraph/storage/triples/neo4j/write.py
Padrão de Implementação (todos os serviços):
- Registrar o manipulador de configuração em
__init__:
# Add after AsyncProcessor initialization
self.register_config_handler(self.on_collection_config)
self.known_collections = set() # Track (user, collection) tuples
- Implementar o gerenciador de configuração:
async def on_collection_config(self, config, version):
"""Handle collection configuration updates"""
logger.info(f"Collection config version: {version}")
if "collections" not in config:
return
# Parse collections from config
# Key format: "user:collection" in config["collections"]
config_collections = set()
for key in config["collections"].keys():
if ":" in key:
user, collection = key.split(":", 1)
config_collections.add((user, collection))
# Determine changes
to_create = config_collections - self.known_collections
to_delete = self.known_collections - config_collections
# Create new collections (idempotent)
for user, collection in to_create:
try:
await self.create_collection_internal(user, collection)
self.known_collections.add((user, collection))
logger.info(f"Created collection: {user}/{collection}")
except Exception as e:
logger.error(f"Failed to create {user}/{collection}: {e}")
# Delete removed collections (idempotent)
for user, collection in to_delete:
try:
await self.delete_collection_internal(user, collection)
self.known_collections.discard((user, collection))
logger.info(f"Deleted collection: {user}/{collection}")
except Exception as e:
logger.error(f"Failed to delete {user}/{collection}: {e}")
- Inicialize as coleções conhecidas na inicialização:
async def start(self):
"""Start the processor"""
await super().start()
await self.sync_known_collections()
async def sync_known_collections(self):
"""Query backend to populate known_collections set"""
# Backend-specific implementation:
# - Milvus/Pinecone/Qdrant: List collections/indexes matching naming pattern
# - Cassandra: Query keyspaces or collection metadata
# - Neo4j/Memgraph/FalkorDB: Query CollectionMetadata nodes
pass
- Refatore os métodos de tratamento existentes:
# Rename and remove response sending:
# handle_create_collection → create_collection_internal
# handle_delete_collection → delete_collection_internal
async def create_collection_internal(self, user, collection):
"""Create collection (idempotent)"""
# Same logic as current handle_create_collection
# But remove response producer calls
# Handle "already exists" gracefully
pass
async def delete_collection_internal(self, user, collection):
"""Delete collection (idempotent)"""
# Same logic as current handle_delete_collection
# But remove response producer calls
# Handle "not found" gracefully
pass
- Remover a infraestrutura de gerenciamento de armazenamento:
Remover a configuração e inicialização de
self.storage_request_consumerRemover a configuração deself.storage_response_producerRemover o método de dispatcher deon_storage_managementRemover as métricas para o gerenciamento de armazenamento Remover as importações:StorageManagementRequest,StorageManagementResponse
Considerações Específicas para o Backend:
Bancos de dados vetoriais (Milvus, Pinecone, Qdrant): Rastrear a lógica (user, collection) em known_collections, mas pode criar múltiplas coleções de backend por dimensão. Continuar o padrão de criação preguiçosa. As operações de exclusão devem remover todas as variantes de dimensão.
Cassandra Objects: As coleções são propriedades de linha, não estruturas. Rastrear informações no nível do keyspace.
Bancos de dados de grafos (Neo4j, Memgraph, FalkorDB): Consultar nós CollectionMetadata na inicialização. Criar/excluir nós de metadados na sincronização.
Cassandra Triples: Usar a API KnowledgeGraph para operações de coleção.
Pontos-Chave do Design:
Consistência eventual: Não há mecanismo de solicitação/resposta, o envio de configuração é transmitido.
Idempotência: Todas as operações de criação/exclusão devem ser seguras para serem repetidas.
Tratamento de erros: Registrar erros, mas não bloquear as atualizações de configuração.
Autorreparação: As operações com falha serão repetidas na próxima atualização de configuração.
Formato da chave da coleção: "user:collection" em config["collections"]
Mudança 11: Atualizar o Esquema da Coleção - Remover Timestamps
Arquivo: trustgraph-base/trustgraph/schema/services/collection.py
Modificar CollectionMetadata (Linhas 13-21):
Remover os campos created_at e updated_at:
class CollectionMetadata(Record):
user = String()
collection = String()
name = String()
description = String()
tags = Array(String())
# Remove: created_at = String()
# Remove: updated_at = String()
Modificar CollectionManagementRequest (linhas 25-47): Remover campos de timestamp:
class CollectionManagementRequest(Record):
operation = String()
user = String()
collection = String()
timestamp = String()
name = String()
description = String()
tags = Array(String())
# Remove: created_at = String()
# Remove: updated_at = String()
tag_filter = Array(String())
limit = Integer()
Justificativa: Os carimbos de data e hora não agregam valor para coleções. O serviço de configuração mantém seu próprio rastreamento de versão. Simplifica o esquema e reduz o armazenamento.
Benefícios da Migração do Serviço de Configuração
- ✅ Elimina tópicos de gerenciamento de armazenamento codificados - Resolve o bloqueio multi-inquilino.
- ✅ Coordenação mais simples - Sem espera assíncrona complexa por 4 ou mais respostas de armazenamento.
- ✅ Consistência eventual - Os serviços de armazenamento são atualizados independentemente por meio de push de configuração.
- ✅ Melhor confiabilidade - Push de configuração persistente versus solicitação/resposta não persistente.
- ✅ Modelo de configuração unificado - Coleções tratadas como configuração.
- ✅ Reduz a complexidade - Remove aproximadamente 300 linhas de código de coordenação.
- ✅ Pronto para multi-inquilino - A configuração já suporta o isolamento de inquilinos por meio de keyspace.
- ✅ Rastreamento de versão - O mecanismo de versão do serviço de configuração fornece um histórico de auditoria.
Notas de Implementação
Compatibilidade com versões anteriores
Alterações de parâmetros:
As alterações de nome dos parâmetros da CLI são alterações disruptivas, mas aceitáveis (o recurso atualmente não está funcional).
Os serviços funcionam sem parâmetros (use os padrões).
Keyspaces padrão preservados: "config", "knowledge", "librarian".
Fila padrão: persistent://tg/config/config
Gerenciamento de coleções: Alteração disruptiva: A tabela de coleções foi removida do keyspace librarian. Nenhuma migração de dados fornecida - aceitável para esta fase. A API de coleção externa não foi alterada (operações de listagem, atualização e exclusão). O formato de metadados da coleção foi simplificado (os carimbos de data e hora foram removidos).
Requisitos de teste
Teste de parâmetros:
- Verificar se o parâmetro
--config-push-queuefunciona no serviço graph-embeddings. - Verificar se o parâmetro
--config-push-queuefunciona no serviço text-completion. - Verificar se o parâmetro
--config-push-queuefunciona no serviço de configuração. - Verificar se o parâmetro
--cassandra-keyspacefunciona para o serviço de configuração. - Verificar se o parâmetro
--cassandra-keyspacefunciona para o serviço cores. - Verificar se o parâmetro
--cassandra-keyspacefunciona para o serviço librarian. - Verificar se os serviços funcionam sem parâmetros (usa os padrões).
- Verificar a implantação multi-inquilino com nomes de fila e keyspace personalizados.
Teste de gerenciamento de coleções:
9. Verificar a operação list-collections por meio do serviço de configuração.
10. Verificar se update-collection cria/atualiza na tabela de configuração.
11. Verificar se delete-collection remove da tabela de configuração.
12. Verificar se o push de configuração é acionado em atualizações de coleção.
13. Verificar se a filtragem de tags funciona com armazenamento baseado em configuração.
14. Verificar se as operações de coleção funcionam sem campos de carimbo de data e hora.
Exemplo de implantação multi-inquilino
# Tenant: tg-dev
graph-embeddings \
-p pulsar+ssl://broker:6651 \
--pulsar-api-key <KEY> \
--config-push-queue persistent://tg-dev/config/config
config-service \
-p pulsar+ssl://broker:6651 \
--pulsar-api-key <KEY> \
--config-push-queue persistent://tg-dev/config/config \
--cassandra-keyspace tg_dev_config
Análise de Impacto
Serviços Afetados pela Alteração 1-2 (Renomeação de Parâmetro da CLI)
Todos os serviços que herdam de AsyncProcessor ou FlowProcessor: config-service cores-service librarian-service graph-embeddings document-embeddings text-completion-* (todos os provedores) extract-* (todos os extractors) query-* (todos os serviços de consulta) retrieval-* (todos os serviços RAG) storage-* (todos os serviços de armazenamento) E mais 20 serviços
Serviços Afetados pelas Alterações 3-6 (Keyspace do Cassandra)
config-service cores-service librarian-service
Serviços Afetados pelas Alterações 7-11 (Gerenciamento de Coleções)
Alterações Imediatas: librarian-service (collection_manager.py, service.py) tables/library.py (remoção da tabela de coleções) schema/services/collection.py (remoção do timestamp)
Alterações Concluídas (Alteração 10): ✅
Todos os serviços de armazenamento (11 no total) - migrados para o push de configuração para atualizações de coleções via CollectionConfigHandler
Esquema de gerenciamento de armazenamento removido de storage.py
Considerações Futuras
Modelo de Keyspace por Usuário
Alguns serviços usam keyspaces por usuário dinamicamente, onde cada usuário recebe seu próprio keyspace do Cassandra:
Serviços com keyspaces por usuário:
- Triples Query Service (
trustgraph-flow/trustgraph/query/triples/cassandra/service.py:65) Usakeyspace=query.user - Objects Query Service (
trustgraph-flow/trustgraph/query/objects/cassandra/service.py:479) Usakeyspace=self.sanitize_name(user) - KnowledgeGraph Direct Access (
trustgraph-flow/trustgraph/direct/cassandra_kg.py:18) Parâmetro padrãokeyspace="trustgraph"
Status: Estes não são modificados nesta especificação.
Revisão Futura Necessária:
Avaliar se o modelo de keyspace por usuário cria problemas de isolamento de locatários
Considerar se as implementações multi-locatário precisam de padrões de prefixo de keyspace (por exemplo, tenant_a_user1)
Revisar para possíveis colisões de ID de usuário entre locatários
Avaliar se um keyspace compartilhado único por locatário com isolamento de linha baseado em usuário é preferível
Observação: Isso não impede a implementação multi-locatário atual, mas deve ser revisado antes das implementações multi-locatário de produção.
Fases de Implementação
Fase 1: Correções de Parâmetros (Alterações 1-6)
Corrigir a nomenclatura do parâmetro --config-push-queue
Adicionar suporte ao parâmetro --cassandra-keyspace
Resultado: Configuração de fila e keyspace multi-locatário habilitada
Fase 2: Migração do Gerenciamento de Coleções (Alterações 7-9, 11)
Migrar o armazenamento de coleções para o serviço de configuração Remover a tabela de coleções do librarian Atualizar o esquema de coleção (remover timestamps) Resultado: Elimina tópicos de gerenciamento de armazenamento codificados, simplifica o librarian
Fase 3: Atualizações do Serviço de Armazenamento (Alteração 10) ✅ CONCLUÍDA
Atualizados todos os serviços de armazenamento para usar o push de configuração para coleções via CollectionConfigHandler
Removida a infraestrutura de solicitação/resposta de gerenciamento de armazenamento
Removidas as definições de esquema legadas
Resultado: Gerenciamento de coleções baseado em configuração completo alcançado
Referências
GitHub Issue: https://github.com/trustgraph-ai/trustgraph/issues/582
Arquivos Relacionados:
trustgraph-base/trustgraph/base/async_processor.py
trustgraph-base/trustgraph/base/cassandra_config.py
trustgraph-base/trustgraph/schema/core/topic.py
trustgraph-base/trustgraph/schema/services/collection.py
trustgraph-flow/trustgraph/config/service/service.py
trustgraph-flow/trustgraph/cores/service.py
trustgraph-flow/trustgraph/librarian/service.py
trustgraph-flow/trustgraph/librarian/collection_manager.py
trustgraph-flow/trustgraph/tables/library.py