- 
                Notifications
    You must be signed in to change notification settings 
- Fork 26
Health Check Improvements #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Changes from 19 commits
      Commits
    
    
            Show all changes
          
          
            25 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      403bb5a
              
                wip: configurable probes
              
              
                stevensJourney c357a1e
              
                use CoreModule in service
              
              
                stevensJourney 1ac789e
              
                fix docker build
              
              
                stevensJourney bfd8ed8
              
                Add JSON Schema
              
              
                stevensJourney d1414f6
              
                cleanup schema and yaml templates
              
              
                stevensJourney 3c1c493
              
                Add comments to PowerSyncConfig
              
              
                stevensJourney f55ae73
              
                comment
              
              
                stevensJourney 043f9df
              
                fix docker build
              
              
                stevensJourney b4fcb37
              
                add probe unit tests
              
              
                stevensJourney 0dcae0d
              
                cleanup router code and naming
              
              
                stevensJourney ae3b79c
              
                improve API for YAML custom tags
              
              
                stevensJourney d747df4
              
                fix typo
              
              
                stevensJourney 443dbfe
              
                revert schema changes
              
              
                stevensJourney 6edfc13
              
                Merge remote-tracking branch 'origin/main' into probes
              
              
                stevensJourney 5995812
              
                fix optionality for healthchecks
              
              
                stevensJourney 21c1dc2
              
                add missing changeset
              
              
                stevensJourney 3549f20
              
                ping liveness probe for API mode
              
              
                stevensJourney 2aec7ee
              
                fix boot log
              
              
                stevensJourney eb5e797
              
                update Open edition tag
              
              
                stevensJourney d56592d
              
                assign timer referrence
              
              
                stevensJourney 1c2f908
              
                Merge remote-tracking branch 'origin/main' into probes
              
              
                stevensJourney fca98b5
              
                Merge branch 'main' into probes
              
              
                stevensJourney eea14d0
              
                Merge branch 'main' into probes
              
              
                stevensJourney d04792c
              
                Merge remote-tracking branch 'origin/main' into probes
              
              
                stevensJourney 6791d8b
              
                update router engine notice
              
              
                stevensJourney File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| --- | ||
| '@powersync/service-core': minor | ||
| --- | ||
|  | ||
| - Added `ServiceContextMode` to `ServiceContext`. This conveys the mode in which the PowerSync service was started in. | ||
| - `RouterEngine` is now always present on `ServiceContext`. The router will only configure actual servers, when started, if routes have been registered. | ||
| - Added typecasting to `!env` YAML custom tag function. YAML config environment variable substitution now supports casting string environment variables to `number` and `boolean` types. | ||
|  | ||
| ```yaml | ||
| replication: | ||
| connections: [] | ||
|  | ||
| storage: | ||
| type: mongodb | ||
|  | ||
| api: | ||
| parameters: | ||
| max_buckets_per_connection: !env PS_MAX_BUCKETS::number | ||
|  | ||
| healthcheck: | ||
| probes: | ||
| use_http: !env PS_MONGO_HEALTHCHECK::boolean | ||
| ``` | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| --- | ||
| '@powersync/service-image': minor | ||
| --- | ||
|  | ||
| - Added typecasting to `!env` YAML custom tag function. YAML config environment variable substitution now supports casting string environment variables to `number` and `boolean` types. | ||
|  | ||
| ```yaml | ||
| replication: | ||
| connections: [] | ||
|  | ||
| storage: | ||
| type: mongodb | ||
|  | ||
| api: | ||
| parameters: | ||
| max_buckets_per_connection: !env PS_MAX_BUCKETS::number | ||
|  | ||
| healthcheck: | ||
| probes: | ||
| use_http: !env PS_MONGO_HEALTHCHECK::boolean | ||
| ``` | ||
|  | ||
| - Added the ability to customize healthcheck probe exposure in the configuration. Backwards compatibility is maintained if no `healthcheck->probes` config is provided. | ||
|  | ||
| ```yaml | ||
| healthcheck: | ||
| probes: | ||
| # Health status can be accessed by reading files (previously always enabled) | ||
| use_filesystem: true | ||
| # Health status can be accessed via HTTP requests (previously enabled for API and UNIFIED service modes) | ||
| use_http: true | ||
| ``` | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@powersync/service-types': minor | ||
| --- | ||
|  | ||
| Added healthcheck types to PowerSyncConfig | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@powersync/lib-services-framework': minor | ||
| --- | ||
|  | ||
| Switched default health check probe mechanism from filesystem to in-memory implementation. Consumers now need to manually opt-in to filesystem probes. | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@powersync/service-module-core': minor | ||
| --- | ||
|  | ||
| Initial core module release. This moves RouterEngine API route registrations, health check probe configuration and metrics configuration from the service runners to this shared module. | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # @powersync/service-module-core | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| # Functional Source License, Version 1.1, Apache 2.0 Future License | ||
|  | ||
| ## Abbreviation | ||
|  | ||
| FSL-1.1-Apache-2.0 | ||
|  | ||
| ## Notice | ||
|  | ||
| Copyright 2023-2024 Journey Mobile, Inc. | ||
|  | ||
| ## Terms and Conditions | ||
|  | ||
| ### Licensor ("We") | ||
|  | ||
| The party offering the Software under these Terms and Conditions. | ||
|  | ||
| ### The Software | ||
|  | ||
| The "Software" is each version of the software that we make available under these Terms and Conditions, as indicated by our inclusion of these Terms and Conditions with the Software. | ||
|  | ||
| ### License Grant | ||
|  | ||
| Subject to your compliance with this License Grant and the Patents, Redistribution and Trademark clauses below, we hereby grant you the right to use, copy, modify, create derivative works, publicly perform, publicly display and redistribute the Software for any Permitted Purpose identified below. | ||
|  | ||
| ### Permitted Purpose | ||
|  | ||
| A Permitted Purpose is any purpose other than a Competing Use. A Competing Use means making the Software available to others in a commercial product or service that: | ||
|  | ||
| 1. substitutes for the Software; | ||
| 2. substitutes for any other product or service we offer using the Software that exists as of the date we make the Software available; or | ||
| 3. offers the same or substantially similar functionality as the Software. | ||
|  | ||
| Permitted Purposes specifically include using the Software: | ||
|  | ||
| 1. for your internal use and access; | ||
| 2. for non-commercial education; | ||
| 3. for non-commercial research; and | ||
| 4. in connection with professional services that you provide to a licensee using the Software in accordance with these Terms and Conditions. | ||
|  | ||
| ### Patents | ||
|  | ||
| To the extent your use for a Permitted Purpose would necessarily infringe our patents, the license grant above includes a license under our patents. If you make a claim against any party that the Software infringes or contributes to the infringement of any patent, then your patent license to the Software ends immediately. | ||
|  | ||
| ### Redistribution | ||
|  | ||
| The Terms and Conditions apply to all copies, modifications and derivatives of the Software. | ||
| If you redistribute any copies, modifications or derivatives of the Software, you must include a copy of or a link to these Terms and Conditions and not remove any copyright notices provided in or with the Software. | ||
|  | ||
| ### Disclaimer | ||
|  | ||
| THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT. | ||
| IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE. | ||
|  | ||
| ### Trademarks | ||
|  | ||
| Except for displaying the License Details and identifying us as the origin of the Software, you have no right under these Terms and Conditions to use our trademarks, trade names, service marks or product names. | ||
|  | ||
| ## Grant of Future License | ||
|  | ||
| We hereby irrevocably grant you an additional license to use the Software under the Apache License, Version 2.0 that is effective on the second anniversary of the date we make the Software available. On or after that date, you may use the Software under the Apache License, Version 2.0, in which case the following will apply: | ||
|  | ||
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|  | ||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|  | ||
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # PowerSync Service Module Core | ||
|  | ||
| Module which registers and configures basic core functionality for PowerSync services. | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| { | ||
| "name": "@powersync/service-module-core", | ||
| "repository": "https://github.com/powersync-ja/powersync-service", | ||
| "types": "dist/index.d.ts", | ||
| "version": "0.0.0", | ||
| "main": "dist/index.js", | ||
| "license": "FSL-1.1-Apache-2.0", | ||
| "type": "module", | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "scripts": { | ||
| "build": "tsc -b", | ||
| "build:tests": "tsc -b test/tsconfig.json", | ||
| "clean": "rm -rf ./dist && tsc -b --clean", | ||
| "test": "vitest" | ||
| }, | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.js", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "./types": { | ||
| "import": "./dist/types/types.js", | ||
| "require": "./dist/types/types.js", | ||
| "default": "./dist/types/types.js" | ||
| } | ||
| }, | ||
| "dependencies": { | ||
| "@powersync/lib-services-framework": "workspace:*", | ||
| "@powersync/service-core": "workspace:*", | ||
| "@powersync/service-rsocket-router": "workspace:*", | ||
| "@powersync/service-types": "workspace:*", | ||
| "fastify": "4.23.2", | ||
| "@fastify/cors": "8.4.1" | ||
| }, | ||
| "devDependencies": {} | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| import cors from '@fastify/cors'; | ||
| import * as framework from '@powersync/lib-services-framework'; | ||
| import * as core from '@powersync/service-core'; | ||
| import { ReactiveSocketRouter } from '@powersync/service-rsocket-router'; | ||
| import fastify from 'fastify'; | ||
|  | ||
| export class CoreModule extends core.modules.AbstractModule { | ||
| constructor() { | ||
| super({ | ||
| name: 'Core' | ||
| }); | ||
| } | ||
|  | ||
| public async initialize(context: core.ServiceContextContainer): Promise<void> { | ||
| this.configureTags(context); | ||
|  | ||
| if ([core.system.ServiceContextMode.API, core.system.ServiceContextMode.UNIFIED].includes(context.serviceMode)) { | ||
| // Service should include API routes | ||
| this.registerAPIRoutes(context); | ||
| } | ||
|  | ||
| // Configures a Fastify server and RSocket server | ||
| this.configureRouterImplementation(context); | ||
|  | ||
| // Configures health check probes based off configuration | ||
| this.configureHealthChecks(context); | ||
|  | ||
| await this.configureMetrics(context); | ||
| } | ||
|  | ||
| protected configureTags(context: core.ServiceContextContainer) { | ||
| core.utils.setTags(context.configuration.metadata); | ||
| } | ||
|  | ||
| protected registerAPIRoutes(context: core.ServiceContextContainer) { | ||
| context.routerEngine.registerRoutes({ | ||
| api_routes: [ | ||
| ...core.routes.endpoints.ADMIN_ROUTES, | ||
| ...core.routes.endpoints.CHECKPOINT_ROUTES, | ||
| ...core.routes.endpoints.SYNC_RULES_ROUTES | ||
| ], | ||
| stream_routes: [...core.routes.endpoints.SYNC_STREAM_ROUTES], | ||
| socket_routes: [core.routes.endpoints.syncStreamReactive] | ||
| }); | ||
| } | ||
|  | ||
| /** | ||
| * Configures the HTTP server which will handle routes once the router engine is started | ||
| */ | ||
| protected configureRouterImplementation(context: core.ServiceContextContainer) { | ||
| context.lifeCycleEngine.withLifecycle(context.routerEngine, { | ||
| start: async (routerEngine) => { | ||
| // The router engine will only start servers if routes have been registered | ||
| await routerEngine.start(async (routes) => { | ||
| const server = fastify.fastify(); | ||
|  | ||
| server.register(cors, { | ||
| origin: '*', | ||
| allowedHeaders: ['Content-Type', 'Authorization', 'User-Agent', 'X-User-Agent'], | ||
| exposedHeaders: ['Content-Type'], | ||
| // Cache time for preflight response | ||
| maxAge: 3600 | ||
| }); | ||
|  | ||
| core.routes.configureFastifyServer(server, { | ||
| service_context: context, | ||
| routes: { | ||
| api: { routes: routes.api_routes }, | ||
| sync_stream: { | ||
| routes: routes.stream_routes, | ||
| queue_options: { | ||
| concurrency: context.configuration.api_parameters.max_concurrent_connections, | ||
| max_queue_depth: 0 | ||
| } | ||
| } | ||
| } | ||
| }); | ||
|  | ||
| const socketRouter = new ReactiveSocketRouter<core.routes.Context>({ | ||
| max_concurrent_connections: context.configuration.api_parameters.max_concurrent_connections | ||
| }); | ||
|  | ||
| core.routes.configureRSocket(socketRouter, { | ||
| server: server.server, | ||
| service_context: context, | ||
| route_generators: routes.socket_routes | ||
| }); | ||
|  | ||
| const { port } = context.configuration; | ||
|  | ||
| await server.listen({ | ||
| host: '0.0.0.0', | ||
| port | ||
| }); | ||
|  | ||
| framework.logger.info(`Running on port ${port}`); | ||
|  | ||
| return { | ||
| onShutdown: async () => { | ||
| framework.logger.info('Shutting down HTTP server...'); | ||
| await server.close(); | ||
| framework.logger.info('HTTP server stopped'); | ||
| } | ||
| }; | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
|  | ||
| protected configureHealthChecks(context: core.ServiceContextContainer) { | ||
| const { | ||
| configuration: { | ||
| healthcheck: { probes } | ||
| } | ||
| } = context; | ||
|  | ||
| const exposesAPI = [core.system.ServiceContextMode.API, core.system.ServiceContextMode.UNIFIED].includes( | ||
| context.serviceMode | ||
| ); | ||
|  | ||
| if (context.serviceMode == core.system.ServiceContextMode.API) { | ||
| /** | ||
| * In the pure API mode we don't currently have any other code which touches the probes. | ||
| * This configures a timer which will touch every 5 seconds. | ||
| */ | ||
| let timer: NodeJS.Timeout | null = null; | ||
| context.lifeCycleEngine.withLifecycle(null, { | ||
| start: () => { | ||
| setInterval(() => { | ||
| context | ||
| .get<framework.ProbeModule>(framework.ContainerImplementation.PROBES) | ||
| .touch() | ||
| .catch((ex) => this.logger.error(`Caught error while updating liveness probe: ${ex}`)); | ||
| }, 5_000); | ||
| }, | ||
| stop: () => { | ||
| if (timer) { | ||
| clearInterval(timer); | ||
| timer = null; | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|  | ||
| /** | ||
| * Maintains backwards compatibility if LEGACY_DEFAULT is present by: | ||
| * - Enabling HTTP probes if the service started in API or UNIFIED mode | ||
| * - Always enabling filesystem probes always exposing HTTP probes | ||
| * Probe types must explicitly be selected if not using LEGACY_DEFAULT | ||
| */ | ||
| if (probes.use_http || (exposesAPI && probes.use_legacy)) { | ||
| context.routerEngine.registerRoutes({ | ||
| api_routes: core.routes.endpoints.PROBES_ROUTES | ||
| }); | ||
| } | ||
|  | ||
| if (probes.use_legacy || probes.use_filesystem) { | ||
| context.register(framework.ContainerImplementation.PROBES, framework.createFSProbe()); | ||
| } | ||
| } | ||
|  | ||
| protected async configureMetrics(context: core.ServiceContextContainer) { | ||
| const apiMetrics = [core.metrics.MetricModes.API]; | ||
| const streamMetrics = [core.metrics.MetricModes.REPLICATION, core.metrics.MetricModes.STORAGE]; | ||
| const metricsModeMap: Partial<Record<core.system.ServiceContextMode, core.metrics.MetricModes[]>> = { | ||
| [core.system.ServiceContextMode.API]: apiMetrics, | ||
| [core.system.ServiceContextMode.SYNC]: streamMetrics, | ||
| [core.system.ServiceContextMode.UNIFIED]: [...apiMetrics, ...streamMetrics] | ||
| }; | ||
|  | ||
| await core.metrics.registerMetrics({ | ||
| service_context: context, | ||
| modes: metricsModeMap[context.serviceMode] ?? [] | ||
| }); | ||
| } | ||
|  | ||
| public async teardown(options: core.modules.TearDownOptions): Promise<void> {} | ||
| } | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from './CoreModule.js'; | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| // No types for this module yet | 
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.