Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #74 from UlfBj/master
Browse files Browse the repository at this point in the history
Feeder template updated to support also sqlite statestorage
  • Loading branch information
petervolvowinz authored Oct 31, 2023
2 parents 0ee2ed3 + e502f8e commit 1c00076
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 21 deletions.
92 changes: 73 additions & 19 deletions feeder/feeder-template/feeder.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
package main

import (
"database/sql"
"encoding/json"
"github.com/akamensky/argparse"
"github.com/go-redis/redis"
_ "github.com/mattn/go-sqlite3"
"github.com/w3c/automotive-viss2/utils"
"io/ioutil"
"math/rand"
Expand All @@ -30,6 +32,10 @@ type FeederMap struct {
VehicleName string `json:"vehicledata"`
}

var redisClient *redis.Client
var dbHandle *sql.DB
var stateDbType string

func readFeederMap(mapFilename string) []FeederMap {
var fMap []FeederMap
data, err := ioutil.ReadFile(mapFilename)
Expand All @@ -48,13 +54,12 @@ func readFeederMap(mapFilename string) []FeederMap {

func initVSSInterfaceMgr(inputChan chan DomainData, outputChan chan DomainData) {
udsChan := make(chan DomainData, 1)
feederClient := initRedisClient()
go initUdsEndpoint(udsChan, feederClient)
go initUdsEndpoint(udsChan)
for {
select {
case outData := <-outputChan:
utils.Info.Printf("Data written to statestorage: Name=%s, Value=%s", outData.Name, outData.Value)
status := redisSet(feederClient, outData.Name, outData.Value, utils.GetRfcTime())
status := statestorageSet(outData.Name, outData.Value, utils.GetRfcTime())
if status != 0 {
utils.Error.Printf("initVSSInterfaceMgr():Redis write failed")
}
Expand All @@ -64,26 +69,35 @@ func initVSSInterfaceMgr(inputChan chan DomainData, outputChan chan DomainData)
}
}

func initRedisClient() *redis.Client {
return redis.NewClient(&redis.Options{
Network: "unix",
Addr: "/var/tmp/vissv2/redisDB.sock",
Password: "",
DB: 1,
})
}
func statestorageSet(path string, val string, ts string) int {
switch stateDbType {
case "sqlite":
stmt, err := dbHandle.Prepare("UPDATE VSS_MAP SET c_value=?, c_ts=? WHERE `path`=?")
if err != nil {
utils.Error.Printf("Could not prepare for statestorage updating, err = %s", err)
return -1
}
defer stmt.Close()

func redisSet(client *redis.Client, path string, val string, ts string) int {
dp := `{"val":"` + val + `", "ts":"` + ts + `"}`
err := client.Set(path, dp, time.Duration(0)).Err()
if err != nil {
utils.Error.Printf("Job failed. Err=%s", err)
return -1
_, err = stmt.Exec(val, ts, path)
if err != nil {
utils.Error.Printf("Could not update statestorage, err = %s", err)
return -1
}
return 0
case "redis":
dp := `{"val":"` + val + `", "ts":"` + ts + `"}`
err := redisClient.Set(path, dp, time.Duration(0)).Err()
if err != nil {
utils.Error.Printf("Job failed. Err=%s", err)
return -1
}
return 0
}
return 0
return -1
}

func initUdsEndpoint(udsChan chan DomainData, redisClient *redis.Client) {
func initUdsEndpoint(udsChan chan DomainData) {
os.Remove("/var/tmp/vissv2/server-feeder-channel.sock")
listener, err := net.Listen("unix", "/var/tmp/vissv2/server-feeder-channel.sock") //the file must be the same as declared in the feeder-registration.json that the service mgr reads
if err != nil {
Expand Down Expand Up @@ -224,14 +238,54 @@ func main() {
Required: false,
Help: "changes log output level",
Default: "info"})
stateDB := parser.Selector("s", "statestorage", []string{"sqlite", "redis", "none"}, &argparse.Options{Required: false,
Help: "Statestorage must be either sqlite, redis, or none", Default: "redis"})
dbFile := parser.String("f", "dbfile", &argparse.Options{
Required: false,
Help: "statestorage database filename",
Default: "../../server/vissv2server/serviceMgr/statestorage.db"})
// Parse input
err := parser.Parse(os.Args)
if err != nil {
utils.Error.Print(parser.Usage(err))
}
stateDbType = *stateDB

utils.InitLog("feeder-log.txt", "./logs", *logFile, *logLevel)

switch stateDbType {
case "sqlite":
var dbErr error
if utils.FileExists(*dbFile) {
dbHandle, dbErr = sql.Open("sqlite3", *dbFile)
if dbErr != nil {
utils.Error.Printf("Could not open state storage file = %s, err = %s", *dbFile, dbErr)
os.Exit(1)
} else {
utils.Info.Printf("SQLite state storage initialised.")
}
} else {
utils.Error.Printf("Could not find state storage file = %s", *dbFile)
}
case "redis":
redisClient = redis.NewClient(&redis.Options{
Network: "unix",
Addr: "/var/tmp/vissv2/redisDB.sock",
Password: "",
DB: 1,
})
err := redisClient.Ping().Err()
if err != nil {
utils.Error.Printf("Could not initialise redis DB, err = %s", err)
os.Exit(1)
} else {
utils.Info.Printf("Redis state storage initialised.")
}
default:
utils.Error.Printf("Unknown state storage type = %s", stateDbType)
os.Exit(1)
}

vssInputChan := make(chan DomainData, 1)
vssOutputChan := make(chan DomainData, 1)
vehicleInputChan := make(chan DomainData, 1)
Expand Down
6 changes: 6 additions & 0 deletions tutorial/content/build-system/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ After the refactoring of these SwCs into one process with ech actor running as a
it became more convenient to build without this script, but it is still [avaliable](https://github.com/w3c/automotive-viss2/blob/master/W3CServer.sh).
For more details, see the "Multi-process vs single-process server implementation" chapter in the README.

### Loggging
Logging can be command line configured at startup.
* logging level can be set to either of [trace, debug, info, warn, error, fatal, panic].
* logging output destination. It can either be written to file, or directed to standard output.
The levels currently used are mainly info, warn, error. Info is appropriate during testing and debugging, while error is appropriate when performance is important.

### Go modules
Go modules are used in multiple places in this project, below follows some commands that may be helpful in managing this.

Expand Down
4 changes: 2 additions & 2 deletions tutorial/content/feeder/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ the state storage to find new write requests.
* Figure 2. Feeder software architecture version 2

A feeder implementing the 2nd version of the SwA is found at the master branch.
This feeder currently only implements the Redis state storage interface, please see the Datastore chapter for Redis details.
This feeder can be configured to either use an SQLite, or a Redis state storage interface, please see the Datastore chapter for details.

A design for how the polling on the server side can be mitigaed is in the planning stage.
A design for how the polling on the server side can be mitigaed is in the planning stage.
It is likely to require an update of the feeder interface.

The feeder translation task is divided into a mapping of the signal name, and a possible scaling of the value.
Expand Down

0 comments on commit 1c00076

Please sign in to comment.