Code Monkey home page Code Monkey logo

libovsdb's People

Contributors

alexanderconstantinescu avatar amorenoz avatar andreaskaris avatar billy99 avatar blacob avatar dave-tucker avatar dcbw avatar dependabot[bot] avatar flavio-fernandes avatar girishmg avatar growler avatar halfcrazy avatar hzhou8 avatar jcaamano avatar lebauce avatar martinkennelly avatar mavenugo avatar nerdalert avatar noah8713 avatar pperiyasamy avatar roytman avatar safchain avatar squeed avatar statapudi avatar trozet avatar vtolstov avatar weiqiangt avatar zhangzujian avatar zshi-redhat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libovsdb's Issues

Error returned when transaction uses "_uuid" as columns

The following code will return empty result and err "Validation failed for the operation". Looks like the client does not like "_uuid" in the transaction

   operation := libovsdb.Operation{
            Op:      "select",
            Table:   tableName,
            Where:   []interface{}{condition},
            Columns: {"_uuid"},
    }

    result, err := db.client.Transact("OpenSwitch", operation)

RFC: Add an explicit Condition

In the context of remote calls (Update(), Delete(), Mutate()) we currently 2 have ways of building Conditions:

  • FromFunc: searches on the cache and adds an Operation per matching element
    • Good: Fully flexible logic
    • Bad: Does not perform well for (one operation per condition plus search the entire cache)
  • FromModel:
    • Good: very concise
    • Good: Better performance
    • Bad: Less flexible (only equality matches on Model fields)

The idea is to have another explicit condition that builds a ovsdb condition object (similarly to what we do for mutations):
The API could look like:

API.Where(API.ExplicitCondition(&obj, []Condition{
    {
       Field: &obj.MyIntegerField,
       Operator: ovsd.ConditionGreaterThan,
       Value: 35,
    }
})).Delete()

It could be integrated into the ConditionFromModel object somehow as well.

Improved Enum support

Currently strong enum typing is not supported. #147 added type alias (e.g: type Alias = string) but, as discussed in that PR, that does not really enforce strong typing limitations.
For that to work we would need to to modify the ovsdb.bindings and mapper layers to cope with named-types.

Once core functionality is added, apart from nice enum validation, we can change replace the type alias with named-types in the generator and should be transparent to clients

Add go generate test

We need to ensure the code we generate works with the API. Need a test for this

Reduce name stutter

A lot of the names of things stutter.
Like ovsdb.OvsSet and client.OvsdbClient
We should try and make this nicer to use.

Add Select operation

Currently, we only support cache-based listing using client.List(). Filtering can be performed by using WhereCache(). However, this makes it mandatory for clients to use Monitor() so the client registers all the DB updates and populates the cache. This has a significant performance (both in terms of memory and cpu) and might not be desired by the user.

We should support RFC7047 Select operation to allow users to inspect the database without having an in-memory copy of it.

My proposal for the API is to leave List() and Get() for cache-based operations and add a new API method called Select that performs the homonym operation.

Don't export `client.Cache()`

Since the client.Get and client.List API do most of the same thing.
This ensures we don't accidentally expose something dangerous (e.g client.Cache().Purge()) to users.
We'd need to ensure that we could still easily write tests without direct cache access though.

Incomplete unmarshalling of content

When a transaction with a "select" operation is used to retrieve data that has complex data, such as a map, the data is not unmarshalled completely. The OVSDB representation needs custom JSON unmarshalling in order to be decoded properly.

My analysis and recommendation:

The OperationResult structure has a Rows field that is defined as:

Rows    []map[string]interface{}

Instead, it could be defined as:

Rows    []Row

Reusing the Row type definition allows the custom unmarshal code to correctly organize the complex data. However, that alters the structure so that code would have to use ....Rows[n].Fields[field] instead of ....Rows[n][field], possibly breaking existing applications.

Another approach would be to define a new type:

type RowResult map[string]interface{}

Then create an unmarshal function for the RowResult type that does the same kind of work that the unmarshal function for the Row type does. And:

Rows []RowResult

Now any previous code that accessed ....Rows[n][field] still works, and the data is correctly unmarshaled.

List() does not work on empty Lists

Currently List() respects the capacity of the given list and does not resize it. This is intended so that a client that preallocates a list for optimization purposes is not returned an increased slice.
However, the side efect is that a zero capacity ([]MyRouter{}) slice does not get populated.
We should consider a slice with capacity==0 in the same way as an nil slice

Add Helpers For Dealing With OperationResults

Dealing with OperationResults is a little tedious.
We should add some helper functions.

E.g:

func (or *operationResults) Errors() []err, which would return all errors from an operation.
It would also be nice to return a typed error e.g ErrConstraintViolated which contains details for each one, so a user could do something like:

res, err := client.Transact(ops...)
if err != nil {
  // handle connection error
 }
if len(res.Errors()) != 0 {
  for _, err := res.Errors() {
    if err == ErrSomethingSafeToIgnore {
      continue
    } else {
      panic(err)
    }
  }
 }

Package Documentation

We have some documentation, but it's not extensive.
We should ensure that:

  1. All packages have a doc.go
  2. All functions that are part of the package API have good documentation
  3. Function comments can avoid mentioning types (e.g does foo with a model.Model) as links are already populated in the godoc.
  4. Examples should be in a doc_test.go file see. This ensures that they compile and won't be forgotten with API changes

Deprecate MonitorAll

As #158 adds a model-based monitoring API we can actually remove MonitorAll.
It would be equivalent to Monitor with no TableMonitor options provided.

Cache-based functions and conditions don't work if Monitoring is disabled

If the user has not enabled Monitoring (client.MonitorAll), the cache is empty.
Predicate conditions (API.ConditionFromFunc()) as well as List() and Get() depend on the cache to work.

For predicate conditions, I'm not arguing we should have them work on cache-less clients but to figure out a good way to report this situation to the user (currently they just return ErrNotFound).

For Get() and List() we could consider generating a select operation

libovsdb does not implement Monitor Cancellation

The library does not provide an api to send a "monitor_cancel" JSON-RPC request

According to the RFC 7047 :

4.1.7. Monitor Cancellation

The "monitor_cancel" request cancels a previously issued monitor
request. The request object members are:

  • "method": "monitor_cancel"

  • "params": []

  • "id":

The in "params" matches the in "params" for
the ongoing "monitor" request that is to be canceled. No more
"update" messages will be sent for this table monitor. The response
to this request has the following members:

  • "result": {}

  • "error": null

  • "id": the request "id" member

In the event that a monitor cancellation request refers to an unknown
monitor request, an error response with the following members is
returned:

  • "result": null

  • "error": "unknown monitor"

  • "id": the request "id" member

Consider making `ovsdb.Operation` an interface

It's used a lot as a return type (e.g client.Create return []ovsdb.Operation and as a parameter in client.Transact

Since there are a number of optional fields, constructing operations yourself can be error prone (and annoying when having to create temporary variables to assign to a *string as literals can't be indirected). To avoid leaking this datastructure outside the OVSDB package, we should consider providing an intermediate type in the client package - like we've done for Condition or Mutation for example:

package client

type Operation interface {
    json.Marshaler
    json.Unmarshaler
}

We'd also want functions to create new Operations, e.g NewInsertOperation, NewDeleteOperation, NewCommentOperation

Error unmarshalling UUID

I'm seing the following error when using libovsdb against the latest OVN Southbound schema

panic: table RBAC_Role, column permissions: failed to extract native element: Wrong Type (OvsToNativeAtomic): expected UUID but got [uuid f7ebfbff-11d3-427a-89c2-a0fab4e0ba88] ([]interface {})

goroutine 1 [running]:
github.com/ovn-org/libovsdb/cache.(*TableCache).Populate(0xc00080e040, 0xc0001ba0c0)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/cache/cache.go:436 +0x725
github.com/ovn-org/libovsdb/client.OvsdbClient.Monitor(0xc0001af260, 0xc000126630, 0xc00020c350, 0xe, 0xc00020c360, 0x7, 0xc000210300, 0xc000804120, 0x1, 0x1, ...)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/client/client.go:339 +0x493
github.com/ovn-org/libovsdb/client.OvsdbClient.MonitorAll(0xc0001af260, 0xc000126630, 0xc00020c350, 0xe, 0xc00020c360, 0x7, 0xc000210300, 0xc000804120, 0x1, 0x1, ...)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/client/client.go:264 +0x274
main.(*OvnShell).Run(0xc000145c80, 0xc000146400, 0xc000116170, 0x0, 0x0)
        /home/amorenoz/code/skydive/ovnmodel/cmd/ovnmon/shell.go:122 +0xff
main.main()
        /home/amorenoz/code/skydive/ovnmodel/cmd/ovnmon/ovnmon.go:57 +0x398

panic in libovsdb.update() callback

I occasionally observe the following panic in my test environment.

+++++++++
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x520fa4]

goroutine 74 [running]:
github.com/mapuri/libovsdb.update(0xc20802e840, 0xc2080c9940, 0x2, 0x4, 0xc2080f6800, 0x0, 0x0)
/var/lib/jenkins/jobs/NetpluginPullRequestSanity/workspace/src/github.com/mapuri/libovsdb/client.go:130 +0x564
reflect.Value.call(0x723400, 0x877570, 0x13, 0x7bdd30, 0x4, 0xc20813bf78, 0x3, 0x3, 0x0, 0x0, ...)
/usr/local/go/src/reflect/value.go:419 +0x10e5
reflect.Value.Call(0x723400, 0x877570, 0x13, 0xc20813bf78, 0x3, 0x3, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:296 +0xbc
github.com/socketplane/libovsdb/Godeps/_workspace/src/github.com/cenkalti/rpc2.func·001(0x0, 0xc208109900, 0x6)
/var/lib/jenkins/jobs/NetpluginPullRequestSanity/workspace/src/github.com/socketplane/libovsdb/Godeps/_workspace/src/github.com/cenkalti/rpc2/client.go:150 +0x1ad
created by github.com/socketplane/libovsdb/Godeps/_workspace/src/github.com/cenkalti/rpc2.(*Client).readRequest
/var/lib/jenkins/jobs/NetpluginPullRequestSanity/workspace/src/github.com/socketplane/libovsdb/Godeps/_workspace/src/github.com/cenkalti/rpc2/client.go:168 +0x5bc
++++++++++

My environment involves multiple go tests, where each test roughly does the following (I have intentionally removed error handling; logic etc for simplicity) :

func SomeTest(t *testing.T) {
  client, err := libovsdb.Connect();
  defer func() { 
     if client {
        client.Disconnect()
     }
  }

  //registers some notification handlers 
  client.Register(myNotifier);
  ...
  //perform some ovs operations
  ...
 }

Based on my understanding of the libovsdb client code I have a potential root-cause, as follows:

In clearConnection() it appears that we set the value pointed by the connection to be nil. I think this leaves a room for a timing window where a go routine (handling ovs notifications over rpc client) might still have some outstanding notifications, while the main go routine (where Disconnect() was called) would have set the value pointed by this key as nil resulting in occasional invalid memory access.

I believe, once a client has called Disconnect() or we receive a disconnect from underlying rpc client, then not keeping the rpc client around shall be okay. So as a fix, I am wondering if deleting the key instead as shown below will help? I have tried it locally and the issues seems to have disappeared for me. Please let me know if this seems like a reasonable fix and I will be happy create a PR.

diff --git a/client.go b/client.go
index 52907a1..6418bdc 100644
--- a/client.go
+++ b/client.go
@@ -231,7 +231,7 @@ func getTableUpdatesFromRawUnmarshal(raw map[string]map[string]RowUpdate) TableU
 }

 func clearConnection(c *rpc2.Client) {
-       connections[c] = nil
+       delete(connections, c)
 }

Remove interfaceToOVSDBNotationInterface

Depends on #116

We should look at using OvsToNative instead. This wasn't done in the original PR as I couldn't figure out how to get the ColumnSchema to be available when marshalling to a struct from JSON.

The alternative to point_up was to indirect access to the value using Value(schema *ColumnSchema) which would convert it, but I disregarded that but because you could use the wrong ColumnSchema AND you had to use NewCondition/Mutation directly and couldn't quickly create instances of the struct.
The other big issue with OvsToNative apart from needing the ColumnSchema was that it assumes sensible types, and doesn't support the "interesting" types we get from the back from the JSON Parser. E.g []interface{}{"set", []interface{}{[]interface{}{"named-uuid", "foo"}, []interface{}{"named-uuid", "bar"}}}

Remove Client.API

It is much more fluent to be able to call client.Get() instead of client.API.Get()

Performance: Improve "Update" performance

The UpdateNotification handling is slow. Looking at pprof I believe this is down to having to marshal/unmarshal to convert the map[string]interface we get from the RPC library to the type we expect from OVSDB.

We should look at:

  • Updating rpc2 to allow methods to have any json serialisable structures as parameters. The deser would be handled only once at this layer
  • Updating rpc2 to pass raw bytes instead of interface{} and have the client-side do the handling

We may also want to look at the possibility of replacing the current rpc library with somethng else (or building our own).

Server Implementation for Integration Testing In Downstream Projects

For example, if I wanted to do and integration test of the client, I could use a real ovsdb-server but this would mean packaging one, running one and tearing it down as part of my test. It would only work if I had called Monitor or MonitorAll and were making assertions based on what was in the client.Cache.

Having a server implementation that operates similarly to ovsdb-server would allow me to:

  1. Start a server from within the Go testing framework with no external dependencies
  2. Inject data in to the server so I can have some information in the DB before the test starts
  3. Make assertions on what is contained in the server database

Fix test failures in encoding_test.go

Tests added in eBay#33 are failing every couple of runs both locally and in CI

=== RUN   TestMarshalMap
    encoding_test.go:172: 
        	Error Trace:	encoding_test.go:172
        	Error:      	Not equal: 
        	            	expected: []interface {}{"map", []interface {}{[]interface {}{"v0", "k0"}, []interface {}{"v1", "k1"}}}
        	            	actual  : []interface {}{"map", []interface {}{[]interface {}{"v1", "k1"}, []interface {}{"v0", "k0"}}}
        	            	
        	            	Diff:
        	            	--- Expected
        	            	+++ Actual
        	            	@@ -4,8 +4,8 @@
        	            	   ([]interface {}) (len=2) {
        	            	+   (string) (len=2) "v1",
        	            	+   (string) (len=2) "k1"
        	            	+  },
        	            	+  ([]interface {}) (len=2) {
        	            	    (string) (len=2) "v0",
        	            	    (string) (len=2) "k0"
        	            	-  },
        	            	-  ([]interface {}) (len=2) {
        	            	-   (string) (len=2) "v1",
        	            	-   (string) (len=2) "k1"
        	            	   }
        	Test:       	TestMarshalMap
        	Messages:   	they should be equal

As you can see from the output, the result is somewhat equal 😉 but the order is not the same.
This is likely because Go doesn't guarantee any order when iterating over map keys, which we do in the MarshalJSON function of the OvsMap type.

We should either:
a) Disable the test
b) Fix the function to test for equality in a better manner

New API

As proposed in #78

This API provides a streamlined and generic way to interface with any OVSDB schema.
A user simply creates structs (which can be auto-generated from a copy of the schema using a tool that will live in this repo), and operations become as easy as:

  • client.Get
  • client.List
  • client.Create
  • client.Update
  • client.Mutate
  • client.Delete

As OVSDB has no Get and List operations, we have to establish a Monitor to replicate the tables in OVSDB in to a cache.

stress: Plot transaction latency

It would be nice if stress were able to plot the time between when Transact was called and when the result of the Transaction was processed by the monitor. Bonus points for tracking the cache propagation time (monitor received to entry in cache)

Cache

As mentioned in #84 and implemented in #75

As OVSDB has no Get and List operations, we have to establish a Monitor to replicate the tables in OVSDB in to a cache.

I therefore propose that we add a cache to the Client by default as well as a UpdateNotifcation handler that populates the cache from a Monitor or MonitorAll.

Most usage of libovsdb has the client do a Connect, set up their handler functions and then call MonitorAll or Monitor.
This makes sense given the information quoted above.

After this PR, a user can simply call Connect then Monitor and they can then interact directly with the cache using a simple API. For example: cache.Table("table_name").Row("named-uuid").

If you do not call Monitor the cache may not be used.

One nice side-effect of the cache is that we can process lifecycle events (add/update/delete) outside of the critical path - i.e we're not stopping the next RPC message from being processed. As such, I recommend that we retire the Register/Unregister API and use the cache.AddEventHandler API instead.

Add multiple elements in a single Create() call

The RFC supports adding multiple rows at once (on a single Operation). But the API accepts a single element. We could extend it to accept a slice of Models or have different function to do such thing.

Not sure how relevant the usecase is though.

Makefile: Look at `make test` target

This fails since #132 was merged as the binaries and generated files have root:root owners and therefore a subsequent make local will fail. It would probably be better to retire make test completely.

Also because we lint before the files are generated

Remove the -local version of targets and make them the canonical ones.
And then ensure that we have a local ovs ready to rock and roll in the integration tests using docker-compose up -d ovs and docker-compose down afterwards.

MonitorAll or Monitor not working

Hello,

It appeals client.go::MonitorAll didn't work. It only calls ovs.Monitor only.
Also the Monitor API is not working.
I am using a pica8 ("1.1.1.4") below switch changing link_state value and run "make test"
func TestMonitor(t *testing.T) {
if testing.Short() {
t.Skip()
}
ovs, err := Connect("1.1.1.4", int(6640))
if err != nil {
log.Fatal("Failed to Connect. error:", err)
panic(err)
}
reply, err := ovs.MonitorAll("Open_vSwitch", nil)
if reply == nil || err != nil {
t.Error("Monitor operation failed with reply=", reply, " and error=", err)
} else {
fmt.Println("MonitorAll=",reply)
}
ovs.Disconnect()
}

The test result:

lab203:~/libovsdb-develop$ make test
go test -covermode=count -coverprofile=coverage.out -v
=== RUN TestOpRowSerialization
--- PASS: TestOpRowSerialization (0.00s)
=== RUN TestOpRowsSerialization
--- PASS: TestOpRowsSerialization (0.00s)
=== RUN TestValidateOvsSet
--- PASS: TestValidateOvsSet (0.00s)
=== RUN TestValidateOvsMap
--- PASS: TestValidateOvsMap (0.00s)
=== RUN TestValidateUuid
--- PASS: TestValidateUuid (0.00s)
=== RUN TestNewUUID
--- PASS: TestNewUUID (0.00s)
=== RUN TestNewNamedUUID
--- PASS: TestNewNamedUUID (0.00s)
=== RUN TestNewCondition
--- PASS: TestNewCondition (0.00s)
=== RUN TestNewMutation
--- PASS: TestNewMutation (0.00s)
=== RUN TestConnect
2015/04/16 14:22:39 Couldnt establish OVSDB connection with Defult params. No big deal
2015/04/16 14:22:39 Succ connected OVSDB on 1.1.1.4
--- PASS: TestConnect (0.01s)
=== RUN TestListDbs
db name= [Open_vSwitch]
--- PASS: TestListDbs (0.01s)
=== RUN TestGetSchemas
db schema= Open_vSwitch
--- PASS: TestGetSchemas (0.02s)
=== RUN TestInsertTransact
Bridge Addition Successful : f3a68e6e-325c-4f54-a4b2-f9221a61a1b1
bridgeUuid= f3a68e6e-325c-4f54-a4b2-f9221a61a1b1
--- PASS: TestInsertTransact (0.02s)
=== RUN TestDeleteTransact
Bridge Delete Successful 1
--- PASS: TestDeleteTransact (0.02s)
=== RUN TestMonitor

======================db,cont,request======================= Open_vSwitch map[SSL:{[bootstrap_ca_cert external_ids private_key certificate ca_cert] {true true true true}} Controller:{[local_netmask controller_rate_limit inactivity_probe is_connected role max_backoff target local_ip enable_async_messages controller_burst_limit other_config connection_mode local_gateway external_ids status] {true true true true}} Wred_Queue:{[drop_probability max_thresh min_thresh enable] {true true true true}} Pica8:{[cos_map_enable combinate_actions_enable lag_advance_hash_mapping_fields l3_ecmp_max_ports l3_mode_enable match_mode xovs_ports l3_mode_table l2_mode_enable proxy_arp_subnet l2_l3_preference l2gre_key_length port_mode xovs_vlans l2_mode_table egress_mode_enable] {true true true true}} QoS:{[external_ids other_config queues type] {true true true true}} sFlow:{[external_ids agent targets polling sampling header] {true true true true}} Mirror:{[output_vlan statistics name select_src_port output_port select_vlan select_dst_port select_all external_ids] {true true true true}} Pica_match_mode:{[priority_low options priority_high name] {true true true true}} Flow_Table:{[groups name flow_limit prefixes overflow_policy] {true true true true}} Port:{[status bond_updelay external_ids tag mac fake_bridge bond_downdelay other_config interfaces lacp bond_fake_iface qos statistics name bond_mode trunks vlan_mode] {true true true true}} Flow_Sample_Collector_Set:{[external_ids bridge id ipfix] {true true true true}} IPFIX:{[cache_max_flows external_ids cache_active_timeout targets obs_domain_id sampling obs_point_id] {true true true true}} Open_vSwitch:{[next_cfg system_version manager_options bridges ssl system_type external_ids statistics ovs_version db_version pica8 cur_cfg other_config] {true true true true}} Interface:{[statistics name link_resets ifindex ingress_policing_rate cfm_fault_status ofport external_ids mtu duplex cfm_mpid cfm_fault cfm_remote_mpids other_config lldp_admin_status ofport_request wred_queues bfd_status admin_state cfm_health mac_in_use bfd link_state lacp_current cfm_flap_count status mac ingress_policing_burst cfm_remote_opstate options type lldp_neighbors link_speed] {true true true true}} NetFlow:{[add_id_to_interface engine_id active_timeout targets engine_type external_ids] {true true true true}} LLDP_Neighbor:{[port_description system_description local_id system_name mgmt_address remote_id] {true true true true}} Manager:{[external_ids status other_config inactivity_probe connection_mode max_backoff is_connected target] {true true true true}} Bridge:{[fail_mode lldp_enable controller flood_vlans sflow datapath_id protocols name external_ids status ipfix ports mirrors datapath_type flow_tables stp_enable other_config netflow] {true true true true}} Queue:{[dscp external_ids other_config] {true true true true}}]

Add libovsdb Benchmarks to CI

The tool in examples/stress is a good start to understanding what bottlenecks, if any, exist in the code.

To reproduce:

docker-compose up -d ovs
# grab ovsdb port number
docker ps
go run ./example/stress/stress.go -cpuprofile prof.out -ovsdb tcp::49163 -ninserts 1000
go tool pprof -http=":8081" prof.out

Here is a sample of 1000 insert operations:
image

For bridge creation, things look reasonable:
image

0.11s was spent on encoding requests and interestingly 0.4s of that was on UUID encoding - validateUUID.

The majority of the program was spent on the libovsdb.update function, which consumes OVSDB update notifications before dispatching them to handlers
image

What's curious here is that we cast the <table_update> parameter to a map[string]interface{}, then json.Marshal it to []byte.
Then we json.Unmarshal the []byte in to a map[string]map[string]RowUpdate. Maybe there is room for improvement here.

I propose the following:

  1. Before we start opening pull requests to speed everything up, I'd like to see if we could add some benchmarks to the unit tests. See here for a guide on how to write them.
  2. Add the -bench flag to go test in CI so we can actually validate that a fix does indeed provide a measurable improvement.

client: Support Multiple Monitor Requests (and maybe resuming Monitor on reconnect)

After #166 has merged we should consider supporting multiple monitors and potentially resuming them on reconnect.
If we could resume on reconnect, then we could quite possibly add an option WithReconnect to reduce the amount of user code to deal with handling disconnects. We'd need to consider whether there would be a Deadline for reconnect before we return an error back to the client, and what that might look like WithReconnet(timeout time.Duration, err chan error)?

Implementation-wise we'd need to think about the following:

  1. We should enforce that the jsonContext for each Monitor is unique
  2. Based on ☝️ we might actually want to generate one and return it to the client. E.g func (o *ovsdbClient) Monitor(...) (uuid, error) so it can be used for MonitorCancel
  3. We should store all current Monitor with options in a map on the ovsdbClient - this will be needed for update() to know which monitor request an update is for. It may also be useful to re-establish monitors after the client has been disconnected

OvsToNative doesn't like pointers to OvsMap/OvsSet

OvsToNative will error if it encounters a pointer to one of the composite types.
The object in question came from mapper.NewRow
We should either adjust NewRow to produce something that OvsToNative can understand, or we should amend OvsToNative to handle pointers.

OpenTelemetry Support

I'm really keen on adding support for opentelemetry.io
This would require:

  1. Adding ctx context.Context to all clientAPI calls, which seems sensible for multiple reasons (i.e timeouts)
  2. Creating spans at useful points in the code, so we can see, for example, how long a given transaction takes
  3. We may also want to expose some metrics for the cache

keep Godoc up to date

Now due to the inconsistency between Godoc and Github, it is hard to automate model installation via go mod.
So please ensure Godoc is up to date with the latest API version.

modelgen: Add support for typed Enum

When we encounter an enum or a set of enums we should generate something like:

type BridgeProtocols string
const (
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
    BridgeProtocolsOpenFlow10 BridgeProtocols = "OpenFlow10"
)

type Bridge struct {
    Protocols []Protocols
}

Cannot insert Southbound DB objects in cache

panic: column datapath,tunnel_key not found in orm info

goroutine 19 [running]:
github.com/ovn-org/libovsdb/cache.(*TableCache).Populate(0xc00019a640, 0xc00063c510)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/cache/cache.go:458 +0x651
github.com/ovn-org/libovsdb/cache.(*TableCache).Update(0xc00019a640, 0x6d2360, 0x95e300, 0xc00063c510)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/cache/cache.go:388 +0x4c
github.com/ovn-org/libovsdb/client.(*OvsdbClient).update(0xc0000d6400, 0xc000078600, 0x2, 0x4, 0xc000634438, 0x0, 0x0)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/client/client.go:211 +0x212
github.com/ovn-org/libovsdb/client.newRPC2Client.func2(0xc00013f2d0, 0xc000078600, 0x2, 0x4, 0xc000634438, 0x0, 0x0)
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/client/client.go:98 +0x52
reflect.Value.call(0x6df240, 0xc0001420a0, 0x13, 0x73826a, 0x4, 0xc000131d78, 0x3, 0x3, 0xc000131cc0, 0x4bbd0b, ...)
        /usr/lib/golang/src/reflect/value.go:476 +0x8e7
reflect.Value.Call(0x6df240, 0xc0001420a0, 0x13, 0xc000131d78, 0x3, 0x3, 0xc000634408, 0xc000131d50, 0x4ee21a)
        /usr/lib/golang/src/reflect/value.go:337 +0xb9
github.com/cenkalti/rpc2.(*Client).handleRequest(0xc00013f2d0, 0x0, 0xc0006244f0, 0x6, 0xc0000d5d00, 0x6cd7c0, 0xc000634408, 0x197)
        /home/amorenoz/code/go/pkg/mod/github.com/cenkalti/[email protected]/client.go:134 +0x1cf
github.com/cenkalti/rpc2.(*Client).readRequest(0xc00013f2d0, 0xc00000e018, 0xc00000e030, 0x0)
        /home/amorenoz/code/go/pkg/mod/github.com/cenkalti/[email protected]/client.go:184 +0x1cb
github.com/cenkalti/rpc2.(*Client).readLoop(0xc00013f2d0)
        /home/amorenoz/code/go/pkg/mod/github.com/cenkalti/[email protected]/client.go:93 +0x165
github.com/cenkalti/rpc2.(*Client).Run(0xc00013f2d0)
        /home/amorenoz/code/go/pkg/mod/github.com/cenkalti/[email protected]/client.go:62 +0x2b
created by github.com/ovn-org/libovsdb/client.newRPC2Client
        /home/amorenoz/code/go/src/github.com/ovn-org/libovsdb/client/client.go:100 +0x491

rpc2 package

Hi. Can you share me info, why this package depend on rpc2?

Consistently return []Operation

All APIs should return []Operation, This makes it easier when dealing with batching operations in to a single transaction

stress: Support multiple clients

Add an -nclients option to cmd/stress this will have each client generate N operations.
This will allow for testing performance of a server when multiple clients are monitoring.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.