-
Notifications
You must be signed in to change notification settings - Fork 0
Development
| Directory | Description |
|---|---|
| src/ | Source tree by module |
| include/ | Header tree by module |
| external/ | Where vcpkg installs its packages |
| scripts/ | Helper scripts |
| python/ | Python libraries for testing; coordinator for deployment; localcluster controller and utilities |
| docker/ | Docker files, scripts |
| cmake/ | CMake helper functions |
| local_cluster/ | Local cluster setup scripts for running cluster using containers on local machine |
| debug/ * | Conditionally created by CMake for debug builds |
| release/ * | Conditionally created by CMake for production builds |
| Filename | Description |
|---|---|
| CMakeLists.txt | Top level CMake file for building code. Add new modules/sub-dirs here. Other configuration should be local to each module |
| vcpkg.json | List of C++ vcpkg dependencies; See list of packages |
| clean.sh / debug.sh / release.sh | Helper scripts, wrapper around CMake to clean, build debug or build release |
| system.json | Properties JSON file for specifying hostnames, and other configuration info for modules |
| python/testing/springtail.py | Initialize redis with properties specified in system.json.* file; bring up system, bring down system, run checks on system |
| python/testing/test_runner.py | Run full system tests, uses springtail.py to bring up and down system, runs tests located in test_cases |
| Name | Description |
|---|---|
| common | Common utilities, springtail_init() should be called in every main; logging, exceptions, concurrent queues, thread pool, etc. |
| storage | Threaded storage layer; B-tree, extent and schema handling and definition |
| pg_repl | Low-level Postgres replication; connecting to primary and decoding replication messages |
| pg_log_mgr | Consumes Postgres replication stream to log, process log, extracts transaction start/commit, inserts commit records into a queue to be consumed by the committer. The committer is responsible for applying log changes to the tables and committing them. |
| write_cache | Cache for holding dirty extents by XID; indexed by Table ID, Extent ID, XID and primary key value |
| xid_mgr | Persistently stores last committed XID |
| benchmarks | Code for benchmarking file system performance (for distributed file systems) |
| proto | gRPC protocol definitions |
| sys_tbl_mgr | System table service & cache; accessed via Thrift; centralizes management of system table metadata |
| proxy | Postgres Proxy that handles read/write splitting sending writes to primary, and reads to FDWs |
| pg_fdw | Postgres frontend query nodes implemented using Postgres Foreign Data Wrapper (FDW) extension; also includes the ddl_daemon for managing DDL changes for the FDW (to create/alter foreign tables) |
| redis | Redis helper classes |
| admin_http | Embedded internal http server |
| pg_ext | Postgres extension related |
Compiling the C++ code is fairly straightforward. All dependencies will be installed via vcpkg; note the first build may take a long time due to downloading and compiling all dependencies.
Make sure all dependencies from Laptop Setup have been installed; otherwise vcpkg deps will not compile
To do a debug build run:
springtail % ./debug.sh # first time build, setups up springtail/debug
springtail % cd debug; make # compile source; or switch to appropriate module
springtail % ./clean.sh. # does a make clean and removes the springtail/debug dir-
Create new subdirs under src/ and include/
-
Add module to top level CMakeLists.txt:
add_subdirectory(src/module) -
Within module (
/src/module/) create a test subdir and a CMakeLists.txt -
Add source code and library dependencies to CMakeLists.txt
-
Add test source code (or helper utils) under
test/subdir- Add to function
springtail_unit_test()toCMakeLists.txt - E.g.
springtail_unit_test(test_replica_shutdown SOURCES test/test_replica_shutdown.cc INCLUDES ${CMAKE_SOURCE_DIR}/include LIBS springtail_proxy GTest::gtest_main ) - Add to function
Run the following command: psql "dbname=springtail user=springtail host=/var/run/postgresql password=springtail”
-
Issue Creation:
- Create a new issue in Linear.
- Clearly describe the feature's functionality and purpose.
- Include relevant details, user stories, or acceptance criteria.
- Assign the issue to yourself if you will be working on it.
-
Branching:
- Once the issue is created, create a new development branch based on the
mainbranch (git checkout -b branch_name).- Use a descriptive branch name that references the issue number (e.g.,
SPR-123-feature or SPR-123-issue).
- Use a descriptive branch name that references the issue number (e.g.,
- Push the newly created branch to your remote repository on GitHub (
git push -u). - If the above push command does not work, do
git push --set-upstream origin <branch name> - If something is wrong and you need to delete remote branch, do
git push -d origin <branch name> - To delete local branch, do
git branch -d <branch name> - To see the list of remote branches and to verify that you have created a remote branch, do
git branch -r
- Once the issue is created, create a new development branch based on the
-
Development:
- Implement the feature code within your development branch.
- Make frequent commits with clear and concise commit messages that describe the specific changes made.
- The commit message should reference the github issue, e.g.,
git commit -m "Fix bug reported ref SPR-123"
- Use unit tests to ensure the functionality of your code.
- Run all tests locally prior to submitting a Pull Request.
- From root of the build tree (e.g., in
springtail/debug/) runmake test
- From root of the build tree (e.g., in
-
Pull Request Creation:
- Once development is complete, create a Pull Request (PR) from your development branch to the
mainbranch. - Reference the issue number in the PR title or description to link the feature to the initial request.
- Provide a clear summary of the changes made and the purpose of the feature.
- Request code reviews from other developers.
- Once development is complete, create a Pull Request (PR) from your development branch to the
-
Review and Merge:
- Address any feedback or suggestions received during the code review process.
- Make necessary code changes and push them to your development branch.
- Rerun all unit and integration tests.
- Once the code is approved for merging, contact @Garth or @Craig to merge into main.
- A squash merge option should be used to merge your changes into the
mainbranch. This creates a single commit representing the entire feature development.
- A squash merge option should be used to merge your changes into the
-
Bring your branch up to date with main:
-
Perform the following commands (best to have done a
git commitlocally before merging):git pull git merge origin/main git push
-
-
Pull in updates from a branch other than main
-
Perform the following commands:
git stash # optional - saves uncommited changes git pull git merge origin/<branch name> # will apply the changes from the branch git push # optional - only if you want to apply the same change to the remote branch git stash pop # optional - get the uncommited changes back and merge if needed
-
If after merge command you want to revert to the pre-merge state, run
git reset --hard ORIG_HEAD -
To see the diff of the last commit, do
git diff HEAD^ -
If you want a remote branch with the name different than your local branch:
- Create branch:
git push --set-upstream origin <local branch>:<remote branch> - Push to remote branch:
git push origin HEAD:<remote branch>
- Create branch:
-
-
Cleanup remote branch view from git:
git remote prune origin -
Delete local branch:
git branch -D <branch name> -
Restore uncommitted, but not staged file:
git restore <filename> -
Restore uncommitted, but staged file:
git restore --staged <filename>
This section outlines how to use a Linux container for development and testing. The Linux container contains a full development environment including compiler, linker, as well as PostgreSQL and Redis servers.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# install if not already installed
brew install colima docker docker-compose docker-BuildxInstall colima and docker (this is preferred); make sure you are using macOS Virtualization.Framework and virtiofs with colima.
If not using Colima, if using Docker Desktop see below.
NOTE: Rosetta is a x86 translation layer, if not using Apple Silicon Mx then it may not be necessary.
# NOTE: 12 = GB memory, use less if needed
# Also if Apple M4, pass --nested-virtualization to make gdb work
colima start --memory 12 --cpu 5 --vm-type=vz --vz-rosetta
# run colima status and check the output
springtail % colima status
INFO[0000] colima is running using macOS Virtualization.Framework
INFO[0000] arch: aarch64
INFO[0000] runtime: docker
INFO[0000] mountType: virtiofsgit clone [git@github.com](mailto:git@github.com):Springtail-inc/springtail.git
cd springtailIf using Docker desktop you may need to set some options to enable Rosetta and VirtioFS. See: https://www.docker.com/blog/docker-desktop-4-25/ Go to Settings→General and select VirtioFS and Rosetta.
From within springtail dir, create the docker image and run it.
- The
-poptions will map the ports from container to host. Use Postgres (5432), Redis (6379) and SSH (22) (only SSH is required). - The
-voption will map your local springtail github source into the container (source:target). The source should be your local springtail dir, the target must be/home/dev/springtail. The source is the location at which you checked out and cloned the github source code; replace<springtail_dir>. - The
--privilegedand--cap-add=SYS_PTRACEoptions may be useful for debugging to attach to a running process
# from springtail root
cd docker
docker-buildx build --progress plain -t springtail:dev -f ./Dockerfile.base .
# note: replace <springtail_dir> with the location of the cloned springtail dir
# ~ is short for /Users/<username>, so use one or the other
docker run -p 2222:22 -p 6666:6379 -v ~/<springtail_dir>:/home/dev/springtail -d --name dev --shm-size=1g -it springtail:dev --privileged --cap-add=SYS_PTRACEThe Dockerfile.base edits the Postgres configuration and creates the script entrypoint.sh as the container entry point. This script ensures the Postgres and Redis services are running, and it creates the Postgres springtail user. The Dockerfile also edits the Postgres configuration as necessary.
You should see 3 directories after logging in:
ssh -p 2222 dev@localhost # use password 'dev'dev@941221cd102e:~$ ls
debug external springtailThe springtail directory should be the mounted directory from your local machine containing the code. The debug directory is where the code will be built within the container, and the external directory will host the vcpkg packages and source.
After reboot if your container is no longer accessible, check if colima is running and if not start it:
> colima start --memory 16 --cpu 5 --vm-type=vz --vz-rosetta
INFO[0000] starting colima
INFO[0000] runtime: docker
WARN[0000] Unable to enable Rosetta: Rosetta2 is not installed
WARN[0000] Run 'softwareupdate --install-rosetta' to install Rosetta2
INFO[0000] starting ... context=vm
INFO[0011] provisioning ... context=docker
INFO[0012] starting ... context=docker
INFO[0012] done Now verify if the docker container is running:
docker container lsIf it did not find anything, the docker container needs to be restarted. Run the following command:
> docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bc0f4fe0fb3 springtail:dev "/usr/local/bin/entr…" 2 weeks ago Exited (255) 24 minutes ago 5432/tcp, 0.0.0.0:2222->22/tcp, [::]:2222->22/tcp, 0.0.0.0:6666->6379/tcp, [::]:6666->6379/tcp dev
The first number is the container id and this is what is needed to get container restarted.
docker container start <container id>Now you can login into your container. If you try to do docker run command instead of docker container start, it will fail as follows:
> docker run -p 2222:22 -p 6666:6379 -v ~/springtail:/home/dev/springtail -d --name dev -it springtail:dev --priviliged --cap-add=SYS_PTRACE
docker: Error response from daemon: Conflict. The container name "/dev" is already in use by container "6bc0f4fe0fb32c62945a411c67b4ddbaf522c6f4fcedbdc4a232d8ac0c9cee63". You have to remove (or rename) that container to be able to reuse that name.
If you have trouble with disk space or RAM or CPU, you can restart colima:
# e.g. 300G disk, 20G RAM, and 6 CPUs
colima start --disk 300 --memory 20 --vz-rosetta --cpu 6 --vm-type=vzYou would need to restart the docker container as specified above.
From within the dev container; this will create symlinks to ../debug and ../external and will start the build. First it will download vcpkg and build it, then it will download the dependency packages and build them, lastly it will build the Springtail code.
# first time; go grab a coffee it may be a while...
cd springtail
./debug.sh
# subsequent times
cd debug
make- Check for the existence of the following two files, and make sure they are symlinks:
debug -> /home/dev/debug/external -> /home/dev/external/
# make sure you are in the springtail dir
cd /home/dev/springtail
# look for debug and external
ls -l
...
lrwxr-xr-x 1 dev dev 16 Oct 4 23:29 debug -> /home/dev/debug/
...
lrwxr-xr-x 1 dev dev 19 Oct 4 23:29 external -> /home/dev/external/
# if they don't exist:
ln -s /home/dev/debug
ln -s /home/dev/external- Sometimes running
./debug.shresults in errors while building the external dependencies in vcpkg. If this happens, just try rerunning./debug.shand see if you can make progress (i.e., check if it is failing on a different dependency, if so keep going).
Since you have mounted the springtail source dir using the -v option when running the docker container, the code it is building is the same code on your local machine. Any edits to the code on your local machine will be reflected in the container. So after you make a code change, just rebuild from the container ( cd debug; make )
If you are using VSCode or Cursor (based on VSCode), and want more functionality to just work, it is best to have VSCode connect to the docker image and edit there. You can do this by installing the “Dev Containers” extension. And then access the Command Palette (cmd+shift+P) and run “Dev Containers: Attach to Running Container…”. You can then select your container. It will first connect as “root”, which is not what you want, so then run “Dev Containers: Open Container Configuration File” and set the contents to the following:
{
"remoteUser": "dev",
"workspaceFolder": "/home/dev/springtail",
}You can then reconnect with “Dev Containers: Attach to Running Container…”. Note that in this environment, you can also install the “CMake” extension and run things like “CMake: Build” and get good language server integration.
Additionally, in VSCode, I’d recommend installing the clangd extension, and also run sudo apt install clangd inside of your container. After installing the VSCode extension, you should get an option to disable “Microsoft Intellisense” (as both extensions provide the same functionality). The clangd extension should give much more accurate/faster support for “Find all references”.