PageSourceSearch

https://hugr-lab.github.io/assets/js/842049e3.ce1cdc91.js

js hugr-lab.github.io collected 2026-10-03 09:19:48 UTC 13,531 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunksite=globalThis.webpackChunksite||[]).push([[4416],{10619(e,s,n){n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"engine-configuration/data-sources/redis","title":"Redis","description":"Redis key-value store data source for caching, counters, and shared state.","source":"@site/docs/4-engine-configuration/1-data-sources/12-redis.md","sourceDirName":"4-engine-configuration/1-data-sources","slug":"/engine-configuration/data-sources/redis","permalink":"/docs/engine-configuration/data-sources/redis","draft":false,"unlisted":false,"editUrl":"https://github.com/hugr-lab/hugr-lab.github.io/docs/4-engine-configuration/1-data-sources/12-redis.md","tags":[],"version":"current","lastUpdatedBy":"vgsml","lastUpdatedAt":1775652736000,"sidebarPosition":12,"frontMatter":{"sidebar_position":12,"title":"Redis","description":"Redis key-value store data source for caching, counters, and shared state."},"sidebar":"docsSidebar","previous":{"title":"LLM (AI Models)","permalink":"/docs/engine-configuration/data-sources/llm"},"next":{"title":"Airport","permalink":"/docs/engine-configuration/data-sources/airport"}}');var t=n(74848),r=n(28453);const c={sidebar_position:12,title:"Redis",description:"Redis key-value store data source for caching, counters, and shared state."},d="Redis Data Source",a={},o=[{value:"Registration",id:"registration",level:2},{value:"Path Format",id:"path-format",level:2},{value:"Examples",id:"examples",level:3},{value:"Usage",id:"usage",level:2},{value:"Read Operations",id:"read-operations",level:3},{value:"Write Operations",id:"write-operations",level:3},{value:"Pub/Sub Operations",id:"pubsub-operations",level:3},{value:"Subscriptions",id:"subscriptions",level:3},{value:"Operations Reference",id:"operations-reference",level:2},{value:"Use with Rate Limiting",id:"use-with-rate-limiting",level:2},{value:"Pub/Sub",id:"pubsub",level:2},{value:"Operations",id:"operations",level:3},{value:"Keyspace Notifications",id:"keyspace-notifications",level:3},{value:"See Also",id:"see-also",level:2}];function l(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"redis-data-source",children:"Redis Data Source"})}),"\n",(0,t.jsxs)(s.p,{children:["Redis data sources provide key-value store operations accessible via the ",(0,t.jsx)(s.a,{href:"#usage",children:(0,t.jsx)(s.code,{children:"core.store"})})," runtime module. Use cases include caching, counters, rate limiting, session storage, and shared state across cluster nodes."]}),"\n",(0,t.jsx)(s.h2,{id:"registration",children:"Registration"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'mutation {\n  core {\n    insert_data_sources(data: {\n      name: "redis"\n      type: "redis"\n      prefix: "redis"\n      path: "redis://:${secret:REDIS_PASSWORD}@redis-host:6379/0"\n    }) { name }\n  }\n}\n'})}),"\n",(0,t.jsx)(s.h2,{id:"path-format",children:"Path Format"}),"\n",(0,t.jsxs)(s.p,{children:["Standard Redis URL: ",(0,t.jsx)(s.code,{children:"redis://[user:password@]host:port/db"})]}),"\n",(0,t.jsxs)(s.p,{children:["Supports ",(0,t.jsx)(s.code,{children:"${secret:ENV_VAR}"})," syntax for credentials via ",(0,t.jsx)(s.code,{children:"ApplyEnvVars"}),"."]}),"\n",(0,t.jsx)(s.h3,{id:"examples",children:"Examples"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"# Local Redis, no auth\nredis://localhost:6379/0\n\n# With password\nredis://:mypassword@redis-host:6379/0\n\n# With env var\nredis://:${secret:REDIS_PASSWORD}@redis-host:6379/0\n\n# Non-default database\nredis://redis-host:6379/3\n"})}),"\n",(0,t.jsx)(s.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(s.p,{children:["Redis sources are accessed through the ",(0,t.jsx)(s.code,{children:"core.store"})," module:"]}),"\n",(0,t.jsx)(s.h3,{id:"read-operations",children:"Read Operations"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'# Get a value (returns null if key doesn\'t exist)\n{ function { core { store {\n  get(store: "redis", key: "session:abc123")\n} } } }\n\n# List keys matching a pattern\n{ function { core { store {\n  keys(store: "redis", pattern: "user:*")\n} } } }\n'})}),"\n",(0,t.jsx)(s.h3,{id:"write-operations",children:"Write Operations"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'# Set a value with optional TTL (seconds)\nmutation { function { core { store {\n  set(store: "redis", key: "session:abc", value: "{\\"user\\":\\"alice\\"}", ttl: 3600) {\n    success message\n  }\n} } } }\n\n# Delete a key\nmutation { function { core { store {\n  del(store: "redis", key: "session:abc") { success }\n} } } }
1\n\n# Atomic increment (creates key with value 1 if not exists)\nmutation { function { core { store {\n  incr(store: "redis", key: "page:views")\n} } } }\n\n# Set TTL on an existing key\nmutation { function { core { store {\n  expire(store: "redis", key: "session:abc", ttl: 300) { success }\n} } } }\n'})}),"\n",(0,t.jsx)(s.h3,{id:"pubsub-operations",children:"Pub/Sub Operations"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'# Publish a message to a channel\nmutation { function { core { store {\n  publish(store: "redis", channel: "notifications", message: "hello world") {\n    success message\n  }\n} } } }\n\n# Configure keyspace notification events (default: KEA = all events)\nmutation { function { core { store {\n  configure_keyspace_events(store: "redis", events: "KEA") {\n    success message\n  }\n} } } }\n'})}),"\n",(0,t.jsx)(s.h3,{id:"subscriptions",children:"Subscriptions"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'# Subscribe to messages on a Pub/Sub channel\nsubscription { core { store {\n  subscribe(store: "redis", channel: "notifications") {\n    channel\n    message\n  }\n} } }\n\n# Watch for keyspace events matching a pattern\nsubscription { core { store {\n  watch(store: "redis", pattern: "__keyevent@0__:*") {\n    key\n    event\n  }\n} } }\n'})}),"\n",(0,t.jsx)(s.h2,{id:"operations-reference",children:"Operations Reference"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Operation"}),(0,t.jsx)(s.th,{children:"Type"}),(0,t.jsx)(s.th,{children:"Returns"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"get"})}),(0,t.jsx)(s.td,{children:"query"}),(0,t.jsxs)(s.td,{children:[(0,t.jsx)(s.code,{children:"String"})," (nullable)"]}),(0,t.jsx)(s.td,{children:"Get value by key"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"keys"})}),(0,t.jsx)(s.td,{children:"query"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"[String]"})}),(0,t.jsx)(s.td,{children:"List keys matching glob pattern"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"set"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"OperationResult"})}),(0,t.jsx)(s.td,{children:"Set key-value with optional TTL"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"del"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"OperationResult"})}),(0,t.jsx)(s.td,{children:"Delete a key"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"incr"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"BigInt"})}),(0,t.jsx)(s.td,{children:"Atomic increment, returns new value"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"expire"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"OperationResult"})}),(0,t.jsx)(s.td,{children:"Set TTL on existing key"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"publish"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"OperationResult"})}),(0,t.jsx)(s.td,{children:"Publish message to a Pub/Sub channel"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"configure_keyspace_events"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"OperationResult"})}),(0,t.jsx)(s.td,{children:"Configure Redis keyspace notifications"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"subscribe"})}),(0,t.jsx)(s.td,{children:"subscription"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"store_message"})}),(0,t.jsx)(s.td,{children:"Subscribe to a Pub/Sub channel"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"watch"})}),(0,t.jsx)(s.td,{children:"subscription"}),(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"store_key_event"})}),(0,t.jsx)(s.td,{children:"Watch keyspace events by pattern"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"use-with-rate-limiting",children:"Use with Rate Limiting"}),"\n",(0,t.jsxs)(s.p,{children:["Redis is used as a shared counter backend for ",(0,t.jsx)(s.a,{href:"/docs/engine-configuration/data-sources/llm#rate-limiting",children:"LLM rate limiting"}),":"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"# LLM s
1ource with Redis-backed rate limits\nhttps://api.openai.com/v1/chat/completions?model=gpt-4o&api_key=...&rpm=100&tpm=100000&rate_store=redis\n"})}),"\n",(0,t.jsx)(s.h2,{id:"pubsub",children:"Pub/Sub"}),"\n",(0,t.jsx)(s.p,{children:"Redis sources support Pub/Sub messaging and keyspace event notifications via GraphQL subscriptions and mutations."}),"\n",(0,t.jsx)(s.h3,{id:"operations",children:"Operations"}),"\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Operation"}),(0,t.jsx)(s.th,{children:"Type"}),(0,t.jsx)(s.th,{children:"Description"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"subscribe"})}),(0,t.jsx)(s.td,{children:"subscription"}),(0,t.jsx)(s.td,{children:"Subscribe to messages on a channel"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"watch"})}),(0,t.jsx)(s.td,{children:"subscription"}),(0,t.jsx)(s.td,{children:"Watch keyspace events matching a pattern"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"publish"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsx)(s.td,{children:"Publish a message to a channel"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"configure_keyspace_events"})}),(0,t.jsx)(s.td,{children:"mutation"}),(0,t.jsxs)(s.td,{children:["Enable Redis keyspace notifications (sets ",(0,t.jsx)(s.code,{children:"notify-keyspace-events"})," config)"]})]})]})]}),"\n",(0,t.jsx)(s.h3,{id:"keyspace-notifications",children:"Keyspace Notifications"}),"\n",(0,t.jsxs)(s.p,{children:["To use ",(0,t.jsx)(s.code,{children:"watch"}),", Redis keyspace notifications must be enabled. Use the ",(0,t.jsx)(s.code,{children:"configure_keyspace_events"})," mutation:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-graphql",children:'mutation { function { core { store {\n  configure_keyspace_events(store: "redis", events: "KEA") {\n    success message\n  }\n} } } }\n'})}),"\n",(0,t.jsxs)(s.p,{children:["This sets the Redis ",(0,t.jsx)(s.code,{children:"notify-keyspace-events"})," configuration. Common values: ",(0,t.jsx)(s.code,{children:"KEA"})," (all events), ",(0,t.jsx)(s.code,{children:"Kg"})," (generic key commands), ",(0,t.jsx)(s.code,{children:"Ks"})," (string commands)."]}),"\n",(0,t.jsxs)(s.p,{children:["See ",(0,t.jsx)(s.a,{href:"/docs/key-value-store#pubsub-subscriptions",children:"Pub/Sub Subscriptions"})," in the Key-Value Store documentation for subscription query examples."]}),"\n",(0,t.jsx)(s.h2,{id:"see-also",children:"See Also"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"/docs/key-value-store",children:"Key-Value Store Module"})," \u2014 full ",(0,t.jsx)(s.code,{children:"core.store"})," API reference"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"/docs/engine-configuration/data-sources/llm",children:"LLM Sources"})," \u2014 AI model providers with rate limiting"]}),"\n",(0,t.jsxs)(s.li,{children:[(0,t.jsx)(s.a,{href:"/docs/ai-models",children:"AI Models Module"})," \u2014 ",(0,t.jsx)(s.code,{children:"core.models"})," API reference"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453(e,s,n){n.d(s,{R:()=>c,x:()=>d});var i=n(96540);const t={},r=i.createContext(t);function c(e){const s=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.