Skip to content

create http dispatcher#91

Open
patrickdemers6 wants to merge 1 commit into
mainfrom
http-producer
Open

create http dispatcher#91
patrickdemers6 wants to merge 1 commit into
mainfrom
http-producer

Conversation

@patrickdemers6

@patrickdemers6 patrickdemers6 commented Dec 20, 2023

Copy link
Copy Markdown
Collaborator

Description

Creating an HTTP dispatcher intended to be used for small-scale personal projects. Data received from a vehicle is delivered through a POST request to the specified http server. The body of this request is JSON to make for easy usage.

The existing dispatchers are great for high reliability, high throughput systems, but for an owner wanting to stream data from their own vehicles, setting up and maintaining this infrastructure is a bit much. This allows enthusiasts to create a simple web server which receives the data.

As called out in the updated Readme, this should not be used in production grade systems. Failed messages are discarded and sending http requests does not scale well.

Type of change

Please select all options that apply to this change:

  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Bug fix (non-breaking change which fixes an issue)
  • Documentation update

Checklist:

Confirm you have completed the following steps:

  • My code follows the style of this project.
  • I have performed a self-review of my code.
  • I have made corresponding updates to the documentation.
  • I have added/updated unit tests to cover my changes.
  • I have added/updated integration tests to cover my changes.

Additional Notes

I am naming the integration tests container so it can be referenced through Docker DNS.

JSON payload format:

{
  "createdAt": "2023-12-21T02:46:51.386927610Z",
  "vin": "device-1"
  "data": [
    {
      "key": "VehicleName",
      "value": {
        "stringValue": "My Test Vehicle"
      }
    },
    {
      "key": "Location",
      "value": {
        "locationValue": {
          "latitude": -37.412374,
          "longitude": 122.145867
        }
      }
    }
  ]
}

Comment thread datastore/http/http.go Outdated
namespace: namespace,
metricsCollector: metricsCollector,
records: requests,
address: config.Address,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can address be localhost? We should prevent that in validateConfig

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you say we should prevent localhost?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will that not mean http producer can call fleet telemetry server itself?

@patrickdemers6 patrickdemers6 Dec 21, 2023

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The producer could call fleet telemetry server but I believe that would be rejected due to invalid certificates. And it would be useless.

The use case I am picturing is a server running with these processes:

  • fleet-telemetry: exposed on port 4443
  • custom-web-server: internally on port 3000. This is what receives vehicle data over http.

Comment thread datastore/http/http.go Outdated
Comment thread datastore/http/http.go Outdated
Comment thread datastore/http/http.go Outdated
Comment thread datastore/http/http.go Outdated
Comment thread test/integration/test.sh
@patrickdemers6 patrickdemers6 force-pushed the http-producer branch 2 times, most recently from bfeb4d8 to 04e67b7 Compare December 21, 2023 03:03
Comment thread datastore/http/http.go
Comment thread datastore/simple/logger.go
Comment thread datastore/simple/logger_test.go Outdated
var _ = Describe("Proto Logger", func() {
var (
protoLogger *simple.ProtoLogger
logger *logrus.Logger

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need logger here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised. This section is a bit complicated due to BeforeEach needing to define an outer and local scope variable from a function that returns multiple values.

Comment thread datastore/simple/logger_test.go Outdated
Comment thread test/integration/integration_test.go Outdated
@patrickdemers6

Copy link
Copy Markdown
Collaborator Author

@agbpatro / @aaronpkahn could I get eyes on this again?

@agbpatro

agbpatro commented Jan 8, 2024

Copy link
Copy Markdown
Collaborator

@agbpatro / @aaronpkahn could I get eyes on this again?

I am still evaluating the value proposition for it. We already have support ZMQ for which small scale developers can use for their application without infra overhead and can do same things which http producer implemented here does

@hauserkristof

Copy link
Copy Markdown

a overhead and can do same things which http producer implemented here does

Hey @agbpatro !

I would really like to see this feature, it is a great idea, and provides a simple and easy solution for integration and PoC codes.

@agbpatro agbpatro left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrickdemers6 can you rebase the PR so that it picks up latest changes and resolve merge conflicts?

Comment thread datastore/http/http.go Outdated

func (p *Producer) sendHTTP(record *telemetry.Record) {
url := fmt.Sprintf("%s?namespace=%s&type=%s", p.address, p.namespace, record.TxType)
payloadJSON, err := record.GetJSONPayload()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change this to record.Payload() to make it consistent with other producers? We have a top level support to send data in json https://github.com/teslamotors/fleet-telemetry/blob/main/README.md#backendsdispatchers

Comment thread datastore/http/http.go Outdated
Comment thread test/integration/integration_test.go
Comment thread datastore/http/http.go Outdated
Comment thread datastore/http/http.go Outdated
Comment thread test/integration/integration_test.go Outdated
Comment thread datastore/http/http.go Outdated
}

func (p *Producer) getRecordChannel(vin string) chan *telemetry.Record {
return p.workerChannels[vinToHash(vin)%uint32(len(p.workerChannels))]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm. I agree with #91 (comment) but at the same time, it could be possible that not all channels will be used (all vins getting partitioned into a single channel or only one vin to stream and increasing worker channel will not make a difference). I guess this is fine since its not going to be recommended producer but maybe we should add a comment in readme about relation between worker channels and vins associated with this account

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's good to call this out. I have added comentary about this to WorkerCount in Config. We could also add a label to http_produce_buffer_size metric calling out size of each worker's buffer. Want me to add this?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sure!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 👍

Comment thread datastore/http/http.go
Comment on lines +161 to +171
contentType := protobufContentType
if p.produceDecodedRecords {
contentType = jsonContentType
}
req.Header.Set("Content-Type", contentType)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to set Content-Type based on json vs protobuf. I'm using application/x-protobuf when it's the proto, but there are not clear standards on this available. Open to suggestion on this.

@Adminius

Copy link
Copy Markdown

Hey @patrickdemers6 any new on this PR?

@patrickdemers6

Copy link
Copy Markdown
Collaborator Author

Haven't looked at this in quite some time! I can rebase sometime soon and try to get this in again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants