diff --git a/foundations/net/.gitattributes b/foundations/net/.gitattributes new file mode 100644 index 0000000000..79a85db5c2 --- /dev/null +++ b/foundations/net/.gitattributes @@ -0,0 +1,14 @@ +# Don't allow people to merge changes to these generated files, because the result +# may be invalid. You need to run "rush update" again. +pnpm-lock.yaml merge=text +shrinkwrap.yaml merge=binary +npm-shrinkwrap.json merge=binary +yarn.lock merge=binary + +# Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic +# syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor +# may also require a special configuration to allow comments in JSON. +# +# For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088 +# +*.json linguist-language=JSON-with-Comments diff --git a/foundations/net/.github/workflows/ci.yml b/foundations/net/.github/workflows/ci.yml new file mode 100644 index 0000000000..ce9256364c --- /dev/null +++ b/foundations/net/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI + +on: + push: + branches: ['main'] + tags: + - 'v0.7.*' + - 's0.7.*' + pull_request: + branches: ['main'] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - uses: actions/setup-node@v3 + with: + node-version: 22 + - name: Verify Change Logs + run: node common/scripts/install-run-rush.js change --verify + - name: Rush Install + run: node common/scripts/install-run-rush.js install + - name: Rush validate + run: node common/scripts/install-run-rush.js validate --verbose + + publish: + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v0.7.') || startsWith(github.ref, 'refs/tags/s0.7.') + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - uses: actions/setup-node@v3 + with: + node-version: 22 + - name: Install dependencies + run: node common/scripts/install-run-rush.js install + - name: Rush validate + run: node common/scripts/install-run-rush.js validate --verbose + - name: Publish packages + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: node common/scripts/install-run-rush.js publish --include-all --publish + + docker: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Configure docker + uses: docker/setup-docker-action@v4 + with: + daemon-config: | + { + "features": { + "containerd-snapshotter": true + } + } + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - uses: actions/setup-node@v3 + with: + node-version: 22 + - name: Verify Change Logs + run: node common/scripts/install-run-rush.js change --verify + - name: Rush Install + run: node common/scripts/install-run-rush.js install + - name: Rush validate + run: node common/scripts/install-run-rush.js validate --verbose + + - name: Docker build + run: | + node common/scripts/install-run-rush.js docker:build -v + docker builder prune -a -f + env: + DOCKER_CLI_HINTS: false + DOCKER_EXTRA: --platform=linux/amd64,linux/arm64 + - name: Login to Docker Hub + if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') || startsWith(github.ref, 'refs/tags/s') }} + uses: docker/login-action@v3 + with: + username: hardcoreeng + password: ${{ secrets.DOCKER_ACCESS_TOKEN }} + - name: Docker push tag + if: ${{ startsWith(github.ref, 'refs/tags/v') || startsWith(github.ref, 'refs/tags/s') }} + run: | + echo Pushing release of tag ${{ github.ref }} + node common/scripts/install-run-rush.js docker:push -v diff --git a/foundations/net/.gitignore b/foundations/net/.gitignore new file mode 100644 index 0000000000..a175778200 --- /dev/null +++ b/foundations/net/.gitignore @@ -0,0 +1,115 @@ +.heft/ +lib/ +_api-extractor-temp/ +temp/ +.idea +pods/workspace/init/ +pods/workspace/init-scripts/ + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +*./rush-logs +*tests/sanity/screenshots + +# Runtime data +*.pid +*.seed +*.pid.lock + +# VS Code settings +.vscode/settings.json + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +# .env + +# next.js build output +.next + +# OS X temporary files +.DS_Store + +# Rush temporary files +common/deploy/ +common/temp/ +common/autoinstallers/*/.npmrc +**/.rush/temp/ +bundle.js +bundle/*.js +dist +.build +typings +types +.validate +tsconfig.tsbuildinfo +ingest-attachment-*.zip +tsdoc-metadata.json +pods/front/dist +*.cpuprofile +*.pyc +metrics.txt +dev/tool/report*.csv +tests/db_dump +.build +.format +tools/apm/apm.js +deploy +metrics.txt +services/github/pod-github/src/github.graphql +.build +.format +dev/tool/report.csv +bundle/* +bundle.js.map +tests/profiles +**/bundle/model.json +.wrangler +dump +**/logs/** +dev/tool/history.json +.aider* +/combined_dependencies +.tmp +ws-tests/docker-compose.override.yml diff --git a/foundations/net/.prettierrc b/foundations/net/.prettierrc new file mode 100644 index 0000000000..00d5897747 --- /dev/null +++ b/foundations/net/.prettierrc @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 120, + "useTabs": false, + "bracketSpacing": true, + "proseWrap": "preserve", + "plugins": [], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} diff --git a/foundations/net/.vscode/extensions.json b/foundations/net/.vscode/extensions.json new file mode 100644 index 0000000000..b8552f9c56 --- /dev/null +++ b/foundations/net/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "svelte.svelte-vscode", + "esbenp.prettier-vscode", + "firsttris.vscode-jest-runner" + ] +} diff --git a/foundations/net/.vscode/launch.json b/foundations/net/.vscode/launch.json new file mode 100644 index 0000000000..aae12dfc9d --- /dev/null +++ b/foundations/net/.vscode/launch.json @@ -0,0 +1,51 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "address": "127.0.0.1", + "localRoot": "${workspaceFolder}", + "name": "Attach to Remote", + "port": 9229, + "request": "attach", + "sourceMaps": true, + "skipFiles": ["/**"], + "type": "node" + }, + { + "name": "Debug Network", + "type": "node", + "request": "launch", + "args": ["src/index.ts"], + "env": { + "PORT": "3737", + "DEVELOPMENT": "true" + }, + "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], + "runtimeVersion": "22", + "showAsyncStacks": true, + "outputCapture": "std", + "sourceMaps": true, + "cwd": "${workspaceRoot}/pods/network-pod", + "protocol": "inspector" + }, + { + "name": "Debug Tool", + "type": "node", + "request": "launch", + "args": ["src/index.ts", "bench-agent"], + "env": { + "NETWORK_HOST": "localhost:37371" + }, + "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], + "runtimeVersion": "22", + "showAsyncStacks": true, + "outputCapture": "std", + "sourceMaps": true, + "cwd": "${workspaceRoot}/pods/network-tool", + "protocol": "inspector" + } + ] +} diff --git a/foundations/net/CHANGELOG.md b/foundations/net/CHANGELOG.md new file mode 100644 index 0000000000..ed1f0cc7aa --- /dev/null +++ b/foundations/net/CHANGELOG.md @@ -0,0 +1,44 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Comprehensive documentation and examples +- GitHub community health files (CONTRIBUTING.md, SECURITY.md) +- Issue and PR templates + +## [0.7.9] - 2025-10-01 + +### Added + +- Initial public release +- Core network implementation with distributed architecture +- ZeroMQ-based RPC communication layer +- Client libraries for network interaction +- Server implementation with multi-client support +- High availability support with stateless containers +- Automatic failover and health monitoring +- Multi-tenant container management +- Comprehensive test suite +- Docker deployment support +- Full documentation and examples + +### Features + +- Distributed load balancing across multiple agents +- Container lifecycle management with reference counting +- Event broadcasting capabilities +- Request/response communication patterns +- Automatic reconnection and retry logic +- Configurable timeouts for different environments +- Label-based container discovery +- Orphaned container detection and cleanup + +[Unreleased]: https://github.com/hcengineering/huly.net/compare/v0.7.9...HEAD +[0.7.9]: https://github.com/hcengineering/huly.net/releases/tag/v0.7.9 diff --git a/foundations/net/CONTRIBUTING.md b/foundations/net/CONTRIBUTING.md new file mode 100644 index 0000000000..737e169e6f --- /dev/null +++ b/foundations/net/CONTRIBUTING.md @@ -0,0 +1,325 @@ +# Contributing to Huly Virtual Network + +First off, thank you for considering contributing to Huly Virtual Network! It's people like you that make this project such a great tool. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [How Can I Contribute?](#how-can-i-contribute) +- [Development Setup](#development-setup) +- [Pull Request Process](#pull-request-process) +- [Coding Standards](#coding-standards) +- [Testing Guidelines](#testing-guidelines) +- [Commit Message Guidelines](#commit-message-guidelines) + +## Code of Conduct + +This project and everyone participating in it is governed by our commitment to providing a welcoming and inspiring community for all. Please be respectful and constructive in your interactions. + +## How Can I Contribute? + +### Reporting Bugs + +Before creating bug reports, please check the existing issues to avoid duplicates. When you create a bug report, include as many details as possible: + +- **Use a clear and descriptive title** +- **Describe the exact steps to reproduce the problem** +- **Provide specific examples** (code snippets, test cases) +- **Describe the behavior you observed** and what you expected +- **Include logs and error messages** +- **Specify your environment** (Node.js version, OS, etc.) + +### Suggesting Enhancements + +Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion: + +- **Use a clear and descriptive title** +- **Provide a detailed description** of the suggested enhancement +- **Explain why this enhancement would be useful** +- **List any alternatives you've considered** + +### Pull Requests + +We actively welcome your pull requests: + +1. Fork the repo and create your branch from `main` +2. If you've added code that should be tested, add tests +3. If you've changed APIs, update the documentation +4. Ensure the test suite passes +5. Make sure your code follows the existing style +6. Issue your pull request! + +## Development Setup + +### Prerequisites + +- **Node.js**: 22.0.0 or higher +- **PNPM**: 10.15.1 or higher (installed automatically via Rush) +- **ZeroMQ**: Native dependencies (libzmq) + +### Initial Setup + +```bash +# Clone your fork +git clone https://github.com/YOUR_USERNAME/huly.net.git +cd huly.net + +# Install dependencies +node common/scripts/install-run-rush.js install + +# Build all packages +node common/scripts/install-run-rush.js build +``` + +### Project Structure + +``` +huly.net/ +├── packages/ +│ ├── core/ # Core network implementation +│ ├── backrpc/ # ZeroMQ RPC layer +│ ├── client/ # Client libraries +│ └── server/ # Server implementation +├── pods/ +│ └── network-pod/ # Docker deployment +├── tests/ # Integration tests +├── examples/ # Example code +└── docs/ # Documentation +``` + +### Development Workflow + +```bash +# Run tests +node common/scripts/install-run-rush.js test + +# Run tests for a specific package +cd packages/core && npm test + +# Build with watch mode (during development) +node common/scripts/install-run-rush.js build:watch + +# Format code +node common/scripts/install-run-rush.js format + +# Validate TypeScript +node common/scripts/install-run-rush.js validate +``` + +## Pull Request Process + +1. **Update Documentation**: Ensure any new features or changes are documented +2. **Add Tests**: Include tests for new functionality +3. **Update CHANGELOG**: Add your changes to the appropriate package CHANGELOG.md +4. **Pass CI**: Ensure all tests pass in CI +5. **Request Review**: Tag relevant maintainers for review +6. **Sign Commits**: Use `git commit -s` to sign off on your commits + +### PR Title Format + +Use descriptive PR titles that follow this format: + +``` +[Package] Brief description of changes + +Examples: +[core] Add support for custom container timeouts +[client] Fix reconnection logic for dropped connections +[docs] Update production deployment guide +``` + +## Coding Standards + +### TypeScript Style + +- **Use TypeScript strict mode**: All code must pass strict type checking +- **Prefer interfaces over types** for object shapes +- **Use async/await** over raw Promises +- **Document public APIs** with JSDoc comments +- **Use descriptive variable names**: No single-letter variables except in loops + +### Code Organization + +```typescript +// 1. Imports (grouped: external, internal, types) +import { EventEmitter } from 'events' +import { NetworkImpl } from '../network' +import type { Container, ContainerUuid } from '../types' + +// 2. Types and interfaces +interface MyOptions { + timeout: number +} + +// 3. Class implementation +export class MyClass { + // Private fields first + private readonly config: MyOptions + + // Constructor + constructor(options: MyOptions) { + this.config = options + } + + // Public methods + async doSomething(): Promise { + // Implementation + } + + // Private methods + private helper(): void { + // Implementation + } +} +``` + +### Error Handling + +- **Always handle errors explicitly**: No silent failures +- **Use typed errors**: Create custom error classes when needed +- **Provide context**: Include relevant information in error messages + +```typescript +// Good +try { + await operation() +} catch (error: any) { + throw new Error(`Failed to perform operation: ${error.message}`) +} + +// Bad +try { + await operation() +} catch (error) { + // Silent failure +} +``` + +## Testing Guidelines + +### Test Structure + +```typescript +describe('ComponentName', () => { + describe('methodName', () => { + it('should behave correctly under normal conditions', async () => { + // Arrange + const component = new ComponentName() + + // Act + const result = await component.methodName() + + // Assert + expect(result).toBe(expected) + }) + + it('should handle error conditions', async () => { + // Test error cases + }) + }) +}) +``` + +### Test Coverage + +- **Aim for 80%+ coverage**: All new code should have tests +- **Test edge cases**: Don't just test the happy path +- **Test error conditions**: Verify error handling works correctly +- **Integration tests**: Add tests that verify component interaction + +### Running Tests + +```bash +# Run all tests +node common/scripts/install-run-rush.js test + +# Run tests for a specific package +cd packages/core +npm test + +# Run tests in watch mode +npm test -- --watch + +# Generate coverage report +npm test -- --coverage +``` + +## Commit Message Guidelines + +We follow conventional commits for clear git history: + +### Format + +``` +(): + + + +