Skip to content

Commit

Permalink
add initial faq, debugging and resources pages
Browse files Browse the repository at this point in the history
  • Loading branch information
jlarfors committed Mar 13, 2024
1 parent b981ce8 commit e137254
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ Check the [examples](./examples/) folder for some examples.
A recommended starting point would be the incredibly useful (joke) [greetings](./examples/greetings/README.md) example.
It has a portal, controller and actor and does not depend on any external services, so there is no added complexity due to third party dependencies.

## Frequently Asked Questions

Check the [FAQ](./docs/faq.md) page.

## Debugging with NATS

Check the [debugging with nats](./docs/debugging_nats.md) page.

## Resources / Learning

Check the [resources](./docs/resources.md) for some material to help you learn NATS and generally about platform engineering.

## Alternatives / Similar tools

Horizon has no opinion about what tools/libraries/SDKs you use to communicate with external services: as you code in Go with Horizon you can do whatever you want.
Expand Down
115 changes: 115 additions & 0 deletions docs/debugging_nats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Debugging NATS

This page tells you how to access NATS directly for any debugging you might want to do.

## Prerequisites

1. Horizon server + NATS server running
2. [NATS CLI](https://github.com/nats-io/natscli) installed

## Using NATS CLI

You will need NATS credentials to access NATS.

TODO: how to generate NATS credentials.

Save this to a file, such as `nats.creds` and `export NATS_CREDS=nats.creds`.

Now you can just call the NATS CLI and access the KV and other streams (remember that NATS KV is just a stream under the hood).

### Listing KVs

```console
nats kv ls
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Key-Value Buckets │
├──────────────────┬──────────────────────────────────────────────┬─────────────────────┬─────────┬────────┬─────────────┤
│ Bucket │ Description │ Created │ Size │ Values │ Last Update │
├──────────────────┼──────────────────────────────────────────────┼─────────────────────┼─────────┼────────┼─────────────┤
│ hz_objects_mutex │ Mutex for hz_objects │ 2024-03-09 19:16:50 │ 0 B │ 0 │ 17h26m25s │
│ hz_session │ KV bucket for storing horizon user sessions. │ 2024-03-09 19:16:50 │ 1.1 KiB │ 6 │ 17h32m19s │
│ hz_objects │ KV bucket for storing horizon objects. │ 2024-03-09 19:16:50 │ 15 KiB │ 26 │ 17h26m26s │
╰──────────────────┴──────────────────────────────────────────────┴─────────────────────┴─────────┴────────┴─────────────╯
```

### Get object from KV

```console
nats kv get hz_objects hz-examples.v1.Greeting.test.Pekka --raw | jq
{
"apiVersion": "hz-examples/v1",
"kind": "Greeting",
"metadata": {
"account": "test",
"managedFields": [
{
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:failureMessage": {},
"f:failureReason": {},
"f:phase": {},
"f:ready": {},
"f:response": {}
}
},
"manager": "ctlr-greetings"
}
],
"name": "Pekka"
},
"spec": {
"name": "Pekka"
},
"status": {
"failureMessage": "",
"failureReason": "",
"phase": "Completed",
"ready": true,
"response": "Greetings, Pekka!"
}
}
```

### Listing Streams

```console
nats stream ls -a
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Streams │
├─────────────────────┬──────────────────────────────────────────────┬─────────────────────┬──────────┬─────────┬──────────────┤
│ Name │ Description │ Created │ Messages │ Size │ Last Message │
├─────────────────────┼──────────────────────────────────────────────┼─────────────────────┼──────────┼─────────┼──────────────┤
│ KV_hz_objects_mutex │ Mutex for hz_objects │ 2024-03-09 21:16:50 │ 0 │ 0 B │ 17h19m32s │
│ KV_hz_session │ KV bucket for storing horizon user sessions. │ 2024-03-09 21:16:50 │ 6 │ 1.1 KiB │ 17h25m26s │
│ KV_hz_objects │ KV bucket for storing horizon objects. │ 2024-03-09 21:16:50 │ 26 │ 15 KiB │ 17h19m33s │
╰─────────────────────┴──────────────────────────────────────────────┴─────────────────────┴──────────┴─────────┴──────────────╯
```

### Consumer Information

```console
nats consumer info KV_hz_objects rc_AgentPool
? Select a Consumer rc_Account
Information for Consumer KV_hz_objects > rc_Account created 2024-03-13T09:05:53+02:00

Configuration:

Name: rc_Account
Description: Reconciler for Account
Pull Mode: true
Deliver Policy: Last Per Subject
Ack Policy: Explicit
Ack Wait: 1m0s
Replay Policy: Instant
Max Waiting Pulls: 512

State:

Last Delivered Message: Consumer sequence: 6 Stream sequence: 88
Acknowledgment floor: Consumer sequence: 6 Stream sequence: 80
Outstanding Acks: 0
Redelivered Messages: 0
Unprocessed Messages: 0
Waiting Pulls: 1 of maximum 512
```
32 changes: 32 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Frequently Asked Questions

## 1. Is Horizon an alternative to Kubernetes?

No. You might run Horizon on Kubernetes, or use Horizon to provision Kubernetes resources.
So why build Horizon? To combine the controller model, an API and a web UI that is easy to extend and test.

For simple environments (e.g. home labs) you could write a container scheduler using controllers and actors and have Horizon run containers for you as an alternative to Kubernetes.

## 2. If we need to automate everything anyway, isn't this just more work?

Absolutely. Using Horizon is more work than just shipping some Terraform or Ansible scripts to end users.
Do some reading on Developer Experience and Platform Engineering.
Architecting abstractions to enable developer flow is not easy and requires effort and time.
The more developers using your platform, the more value there is in doing so.

## 3. Horizon is immature, can I trust it?

Horizon is very immature, not a CNCF project and there is no community (yet).
However, Horizon is just a thin layer on top of [NATS](https://nats.io/).
NATS is a very robust and mature technology that you can trust and Horizon makes no effort to "hide away" NATS, making it very easy to access NATS directly.
See the [debugging with nats](./debugging_nats.md) page.

## 4. If I start developing on Horizon, will I get "locked in"?

If you are solving problems that have fairly high essential complexity, then doing so with many tools glued together (bash, make, terraform, github actions etc.) adds a lot to the accidental complexity and makes it harder to test and maintain implementation.

With Horizon you will write Go code that can be reused outside of Horizon.
Reconcile logic could be ported to CI pipelines or some other automated event.
Portals are just Go servers that you could run somewhere else.

Like any tool, you will have to invest in Horizon to make it meaningful, but the idea that you get "locked in" because you write Go code (as opposed to bash) is an unfounded one.
19 changes: 19 additions & 0 deletions docs/resources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Resources

## Learning NATS

1. [The coolest OSS project you've never heard of: NATS Getting started!](https://youtu.be/hjXIUPZ7ArM?si=-2nazkTI3OTHprUz)
NATS is a connective technology powering modern distributed systems, unifying Cloud, On-Premise, Edge, and IoT.

2. [JetStream KV: A fascinating alternative to Redis](https://youtu.be/XLJ5_5MsgGQ?si=7OQuxbUXW1QGwKSi)

This talk dives into the details of how NATS JetStream's Key/Value buckets work, and showcases how easy it is to move and replicate data without having to change your applications.

## Platform Engineering

1. [Build Abstractions not Illusions - Gregor Hohpe - YOW! 2023](https://youtu.be/aWZFRk-w3ng?si=aM8CGTLnI8Jm41Bt)

Abstract:
Let’s be honest, the tech we have today is amazing but it can also be complex. So, it’s only natural that the platforms we build want to hide that complexity to improve productivity, avoid mistakes, and reduce cognitive load. So, the more complexity we can hide, the better our platform?
Actually no - we need to be careful that we create useful abstractions, not dangerous illusions.
This talk reflects on two decades of building complex distributed systems, highlighting where abstractions helped and where illusions led to major disappointments.

0 comments on commit e137254

Please sign in to comment.