text:
# gRPC xDS Loadbalancing

Sample gRPC client/server application using the **Experimental** [xDS-Based Global Load Balancing](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md)

As it is experimental, any of this can change at anytime and break...

_caveat emptor_

>> ..this repo and code is not supported by google..

The reason i wrote this was to understand what is going on and to dig into the bit left unanswered in [gRPC xDS example](https://github.com/grpc/grpc-go/blob/master/examples/features/xds/README.md)

_"This example doesn't include instructions to setup xDS environment. Please refer to documentation specific for your xDS management server."_

This sample app does really nothing special:

You run two gRPC servers on the same host on two different ports

You start an xDS server in go that replays the protocol to let the gRPC clients know where to connect to

When the client first bootstraps to the xDS server, it sends down instructions to connect directly to one gRPC server instance.

Then wait a minute (really)

The xDS server will rotate the valid backend endpoint targets 60 seconds after it starts up (a trivial example, truly).  The second target is the second port where the second gRPC endpoint is running.

thats it.

---

## Setup

edit `/etc/hosts`

```bash
<IP_ADDRESS> be.cluster.local xds.domain.com
```

## gRPC Server

Start gRPC Servers

```bash
cd app/
go run src/grpc_server.go --grpcport :50051 --servername server1
go run src/grpc_server.go --grpcport :50052 --servername server1
```

> **NOTE** If you change the ports or run more servers, ensure you update the list when you start the xDS server

## gRPC Client (DNS)

Enable debug tracing on the client; the whole intent is to see all the details!

```bash
export GRPC_GO_LOG_VERBOSITY_LEVEL=99
export GRPC_GO_LOG_SEVERITY_LEVEL=info
```

Use DNS as the bootstrap mechanism to connec to the server:

```bash
$ go run src/grpc_client.go --host dns:///be.cluster.local:50051

INFO: 2020/04/21 15:25:11 parsed scheme: "dns"
INFO: 2020/04/21 15:25:11 ccResolverWrapper: sending update to cc: {[{<IP_ADDRESS>:50051  <nil> 0 <nil>}] <nil> <nil>}
INFO: 2020/04/21 15:25:11 ClientConn switching balancer to "pick_first"
INFO: 2020/04/21 15:25:11 Channel switches to new LB policy "pick_first"
INFO: 2020/04/21 15:25:11 Subchannel Connectivity change to CONNECTING
INFO: 2020/04/21 15:25:11 blockingPicker: the picked transport is not ready, loop back to repick
INFO: 2020/04/21 15:25:11 Subchannel picks a new address "<IP_ADDRESS>:50051" to connect
INFO: 2020/04/21 15:25:11 pickfirstBalancer: HandleSubConnStateChange: 0xc00015bfa0, {CONNECTING <nil>}
INFO: 2020/04/21 15:25:11 Channel Connectivity change to CONNECTING
INFO: 2020/04/21 15:25:11 Subchannel Connectivity change to READY
INFO: 2020/04/21 15:25:11 pickfirstBalancer: HandleSubConnStateChange: 0xc00015bfa0, {READY <nil>}
INFO: 2020/04/21 15:25:11 Channel Connectivity change to READY

2020/04/21 15:25:12 RPC Response: 0 message:"Hello unary RPC msg   from hostname srashid1"

INFO: 2020/04/21 15:25:12 Channel Connectivity change to SHUTDOWN
INFO: 2020/04/21 15:25:12 Subchannel Connectivity change to SHUTDOWN
```

## xDS Server

Now start the xDS server:

```bash
cd xds
go run main.go --upstream_port=50051 --upstream_port=50052

INFO[0000] Starting control plane
INFO[0000] gateway listening HTTP/1.1                    port=18001
INFO[0000] management server listening                   port=18000
```

> **NOTE** Update the list of `--upstream_port` flags to reflect the list of ports for the gRPC servers that you started

## gRPC Client (xDS)

Ensure the xds Bootstrap file specifies the correct `server_url`

The grpc client will connect to this as the the xDS server.  The gRPC client library looks for a specific env-var (`GRPC_XDS_BOOTSTRAP`) that points to the file

- `xds_bootstrap.json`:
```json
{
  "xds_servers": [
    {
      "server_uri": "xds.domain.com:18000"
    }
  ],
  "node": {
    "id": "b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>",
    "metadata": {
      "R_PROJECT_NUMBER": "123456789012"
    },
    "locality": {
      "zone": "us-central1-a"
    }
  }
}
```

Then:

```bash
export GRPC_XDS_BOOTSTRAP=`pwd`/xds_bootstrap.json
```

Then:

```bash
go run src/grpc_client.go --host xds-experimental:///be-srv
```

in the debug logs that it connected to port `:50051`

```console
INFO: 2020/04/21 16:14:42 Subchannel picks a new address "be.cluster.local:50051" to connect
```

The grpc client will issue grpc requests every 5 seconds using the list of backend services it gets from the xds server.
Since the xds server will abruptly rotate the grpc backend servers, the client will suddenly connect to `server2`

```console
INFO: 2020/04/21 16:16:08 Subchannel picks a new address "be.cluster.local:50052" to connect
```

The port it connected to is `:50052`

Right, that's it!

---

```
$ go run src/grpc_client.go --host xds-experimental:///be-srv
2020/11/09 08:28:59 RPC Response: 0 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:04 RPC Response: 1 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:09 RPC Response: 2 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:14 RPC Response: 3 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:19 RPC Response: 4 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:24 RPC Response: 5 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:29 RPC Response: 6 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:34 RPC Response: 7 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:39 RPC Response: 8 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:44 RPC Response: 9 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:49 RPC Response: 10 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:54 RPC Response: 11 message:"Hello unary RPC msg   from server1"
2020/11/09 08:29:59 RPC Response: 12 message:"Hello unary RPC msg   from server2"   <<<<<<<<
2020/11/09 08:30:04 RPC Response: 13 message:"Hello unary RPC msg   from server2"
2020/11/09 08:30:09 RPC Response: 14 message:"Hello unary RPC msg   from server2"

```

---

If you want more details...

## References

- [Envoy Listener proto](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/listener.proto)
- [Envoy Cluster proto](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/cluster.proto)
- [Envoy Endpoint proto](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/endpoint.proto)

### xDS Server start

```bash
INFO[0000] Starting control plane
INFO[0000] gateway listening HTTP/1.1                    port=18001
INFO[0000] management server listening                   port=18000
INFO[0010] OnStreamOpen 1 open for Type []
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.Listener]
INFO[0010] cb.Report()  callbacks                        fetches=0 requests=1
INFO[0010] >>>>>>>>>>>>>>>>>>> creating NodeID b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>
INFO[0010] >>>>>>>>>>>>>>>>>>> creating ENDPOINT for remoteHost:port be.cluster.local:50051
INFO[0010] >>>>>>>>>>>>>>>>>>> creating CLUSTER be-srv-cluster
INFO[0010] >>>>>>>>>>>>>>>>>>> creating RDS be-srv-vs
INFO[0010] >>>>>>>>>>>>>>>>>>> creating LISTENER be-srv
INFO[0010] >>>>>>>>>>>>>>>>>>> creating snapshot Version 1
INFO[0010] OnStreamResponse... 1   Request [type.googleapis.com/envoy.api.v2.Listener],  Response[type.googleapis.com/envoy.api.v2.Listener]
INFO[0010] cb.Report()  callbacks                        fetches=0 requests=1
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.RouteConfiguration]
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.Listener]
INFO[0010] OnStreamResponse... 1   Request [type.googleapis.com/envoy.api.v2.RouteConfiguration],  Response[type.googleapis.com/envoy.api.v2.RouteConfiguration]
INFO[0010] cb.Report()  callbacks                        fetches=0 requests=3
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.RouteConfiguration]
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.Cluster]
INFO[0010] OnStreamResponse... 1   Request [type.googleapis.com/envoy.api.v2.Cluster],  Response[type.googleapis.com/envoy.api.v2.Cluster]
INFO[0010] cb.Report()  callbacks                        fetches=0 requests=5
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.Cluster]
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.ClusterLoadAssignment]
INFO[0010] OnStreamResponse... 1   Request [type.googleapis.com/envoy.api.v2.ClusterLoadAssignment],  Response[type.googleapis.com/envoy.api.v2.ClusterLoadAssignment]
INFO[0010] cb.Report()  callbacks                        fetches=0 requests=7
INFO[0010] OnStreamRequest 1  Request[type.googleapis.com/envoy.api.v2.ClusterLoadAssignment]
INFO[0011] OnStreamClosed 1 closed
```

### gRPC Client Call #1

```log
$ go run src/grpc_client.go --host xds-experimental:///be-srv

INFO: 2020/04/21 16:14:42 parsed scheme: "xds-experimental"
INFO: 2020/04/21 16:14:42 [xds-bootstrap] Got bootstrap file location from GRPC_XDS_BOOTSTRAP environment variable: /home/srashid/Desktop/xds_grpc/app/xds_bootstrap.json
INFO: 2020/04/21 16:14:42 [xds-bootstrap] Bootstrap content: {
  "xds_servers": [
    {
      "server_uri": "xds.domain.com:18000"
    }
  ],---

    "locality": {
      "zone": "us-central1-a"
    }
  }
}
INFO: 2020/04/21 16:14:42 [xds-bootstrap] Bootstrap config for creating xds-client: &{BalancerName:xds.domain.com:18000 Creds:<nil> NodeProto:id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" }
INFO: 2020/04/21 16:14:42 [xds-resolver 0xc000203900] Creating resolver for target: {Scheme:xds-experimental Authority: Endpoint:be-srv}
WARNING: 2020/04/21 16:14:42 [xds-resolver 0xc000203900] No credentials available, using Insecure
INFO: 2020/04/21 16:14:42 parsed scheme: ""
INFO: 2020/04/21 16:14:42 scheme "" not registered, fallback to default scheme
INFO: 2020/04/21 16:14:42 ccResolverWrapper: sending update to cc: {[{xds.domain.com:18000  <nil> 0 <nil>}] <nil> <nil>}
INFO: 2020/04/21 16:14:42 ClientConn switching balancer to "pick_first"
INFO: 2020/04/21 16:14:42 Channel switches to new LB policy "pick_first"
INFO: 2020/04/21 16:14:42 Subchannel Connectivity change to CONNECTING
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Created ClientConn to xDS server: xds.domain.com:18000
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Created
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.Listener, resource names: [be-srv]
INFO: 2020/04/21 16:14:42 [xds-resolver 0xc000203900] Watch started on resource name be-srv with xds-client 0xc00011a870
INFO: 2020/04/21 16:14:42 Subchannel picks a new address "xds.domain.com:18000" to connect
INFO: 2020/04/21 16:14:42 pickfirstBalancer: HandleSubConnStateChange: 0xc00024e0f0, {CONNECTING <nil>}
INFO: 2020/04/21 16:14:42 Channel Connectivity change to CONNECTING
INFO: 2020/04/21 16:14:42 Subchannel Connectivity change to READY
INFO: 2020/04/21 16:14:42 pickfirstBalancer: HandleSubConnStateChange: 0xc00024e0f0, {READY <nil>}
INFO: 2020/04/21 16:14:42 Channel Connectivity change to READY
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS stream created
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv" type_url:"type.googleapis.com/envoy.api.v2.Listener"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received, type: type.googleapis.com/envoy.api.v2.Listener
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received: version_info:"1" resources:<type_url:"type.googleapis.com/envoy.api.v2.Listener" value:"\n\006be-srv\232\001z\nx\n`type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager\022\024\032\022\n\002\032\000\022\014be-srv-route" > type_url:"type.googleapis.com/envoy.api.v2.Listener" nonce:"1"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name: be-srv, type: *envoy_api_v2.Listener, contains: name:"be-srv" api_listener:<api_listener:<type_url:"type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager" value:"\032\022\n\002\032\000\022\014be-srv-route" > >
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with type *envoy_config_filter_network_http_connection_manager_v2.HttpConnectionManager, contains rds:<config_source:<ads:<> > route_config_name:"be-srv-route" >
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] xds: client received LDS update: {routeName:be-srv-route}, err: <nil>
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.RouteConfiguration, resource names: [be-srv-route]
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.Listener, version: 1, nonce: 1
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-route" type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: version_info:"1" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv" type_url:"type.googleapis.com/envoy.api.v2.Listener" response_nonce:"1"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received, type: type.googleapis.com/envoy.api.v2.RouteConfiguration
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received: version_info:"1" resources:<type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" value:"\n\014be-srv-route\022+\n\tbe-srv-vs\022\006be-srv\032\026\n\002\n\000\022\020\n\016be-srv-cluster" > type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" nonce:"2"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name: be-srv-route, type: *envoy_api_v2.RouteConfiguration, contains: name:"be-srv-route" virtual_hosts:<name:"be-srv-vs" domains:"be-srv" routes:<match:<prefix:"" > route:<cluster:"be-srv-cluster" > > >
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name be-srv-route, type string, value be-srv-cluster added to cache
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] xds: client received RDS update: {clusterName:be-srv-cluster}, err: <nil>
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.RouteConfiguration, version: 1, nonce: 2
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: version_info:"1" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-route" type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" response_nonce:"2"
INFO: 2020/04/21 16:14:42 [xds-resolver 0xc000203900] Received update on resource be-srv from xds-client 0xc00011a870, generated service config: {
    "loadBalancingConfig":[
      {
        "cds_experimental":{
          "Cluster": "be-srv-cluster"
        }
      }
    ]
  }
INFO: 2020/04/21 16:14:42 ccResolverWrapper: sending update to cc: {[] 0xc000256600 0xc0002e6050}
INFO: 2020/04/21 16:14:42 ClientConn switching balancer to "cds_experimental"
INFO: 2020/04/21 16:14:42 Channel switches to new LB policy "cds_experimental"
INFO: 2020/04/21 16:14:42 [cds-lb 0xc000258750] Created
INFO: 2020/04/21 16:14:42 [cds-lb 0xc000258750] Receive update from resolver, balancer config: &{LoadBalancingConfig:<nil> ClusterName:be-srv-cluster}
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.Cluster, resource names: [be-srv-cluster]
INFO: 2020/04/21 16:14:42 [cds-lb 0xc000258750] Watch started on resource name be-srv-cluster with xds-client 0xc00011a870
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.Cluster"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received, type: type.googleapis.com/envoy.api.v2.Cluster
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received: version_info:"1" resources:<type_url:"type.googleapis.com/envoy.api.v2.Cluster" value:"\n\016be-srv-cluster\032\004\n\002\032\000\020\003" > type_url:"type.googleapis.com/envoy.api.v2.Cluster" nonce:"3"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name: be-srv-cluster, type: *envoy_api_v2.Cluster, contains: name:"be-srv-cluster" type:EDS eds_cluster_config:<eds_config:<ads:<> > >
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name be-srv-cluster, type client.CDSUpdate, value {ServiceName:be-srv-cluster EnableLRS:false} added to cache
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.Cluster, version: 1, nonce: 3
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: version_info:"1" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.Cluster" response_nonce:"3"
INFO: 2020/04/21 16:14:42 [cds-lb 0xc000258750] Watch update from xds-client 0xc00011a870, content: {ServiceName:be-srv-cluster EnableLRS:false}
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Created
INFO: 2020/04/21 16:14:42 [cds-lb 0xc000258750] Created child policy 0xc000258820 of type eds_experimental
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Receive update from resolver, balancer config: &{LoadBalancingConfig:<nil> BalancerName: ChildPolicy:<nil> FallBackPolicy:<nil> EDSServiceName:be-srv-cluster LrsLoadReportingServerName:<nil>}
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment, resource names: [be-srv-cluster]
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Watch started on resource name be-srv-cluster with xds-client 0xc00011a870
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received, type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS response received: version_info:"1" resources:<type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" value:"\n\016be-srv-cluster\022C\n\034\n\013us-central1\022\rus-central1-a\022\036\020\001\n\032\n\030\n\026\022\020be.cluster.local\030\203\207\003\032\003\010\350\007" > type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" nonce:"4"
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Resource with name: be-srv-cluster, type: *envoy_api_v2.ClusterLoadAssignment, contains: cluster_name:"be-srv-cluster" endpoints:<locality:<region:"us-central1" zone:"us-central1-a" > lb_endpoints:<endpoint:<address:<socket_address:<address:"be.cluster.local" port_value:50051 > > > health_status:HEALTHY > load_balancing_weight:<value:1000 > >
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Watch update from xds-client 0xc00011a870, content: &{Drops:[] Localities:[{Endpoints:[{Address:be.cluster.local:50051 HealthStatus:1 Weight:0}] ID:us-central1-us-central1-a- Priority:0 Weight:1000}]}
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment, version: 1, nonce: 4
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] New priority 0 added
INFO: 2020/04/21 16:14:42 [xds-client 0xc00011a870] ADS request sent: version_info:"1" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" response_nonce:"4"
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] New locality us-central1-us-central1-a- added
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Switching priority from unset to 0
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Created child policy 0xc00042a0a0 of type round_robin
INFO: 2020/04/21 16:14:42 base.baseBalancer: got new ClientConn state:  {{[{be.cluster.local:50051  <nil> 0 <nil>}] <nil> <nil>} <nil>}
INFO: 2020/04/21 16:14:42 Subchannel Connectivity change to CONNECTING
INFO: 2020/04/21 16:14:42 Subchannel picks a new address "be.cluster.local:50051" to connect
INFO: 2020/04/21 16:14:42 base.baseBalancer: handle SubConn state change: 0xc000266740, CONNECTING
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Balancer state update from locality us-central1-us-central1-a-, new state: {ConnectivityState:CONNECTING Picker:0xc0002666f0}
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Child pickers with weight: map[us-central1-us-central1-a-:weight:1000,picker:0xc0002556d0,state:CONNECTING]
INFO: 2020/04/21 16:14:42 Channel Connectivity change to CONNECTING
INFO: 2020/04/21 16:14:42 Subchannel Connectivity change to READY
INFO: 2020/04/21 16:14:42 base.baseBalancer: handle SubConn state change: 0xc000266740, READY
INFO: 2020/04/21 16:14:42 roundrobinPicker: newPicker called with info: {map[0xc000266740:{{be.cluster.local:50051  <nil> 0 <nil>}}]}
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Balancer state update from locality us-central1-us-central1-a-, new state: {ConnectivityState:READY Picker:0xc00031c4b0}
INFO: 2020/04/21 16:14:42 [eds-lb 0xc000258820] Child pickers with weight: map[us-central1-us-central1-a-:weight:1000,picker:0xc0002b21e0,state:READY]
INFO: 2020/04/21 16:14:42 Channel Connectivity change to READY
2020/04/21 16:14:43 RPC Response: 0 message:"Hello unary RPC msg   from hostname srashid1"
INFO: 2020/04/21 16:14:43 Channel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:14:43 [xds-resolver 0xc000203900] Watch cancel on resource name be-srv with xds-client 0xc00011a870
INFO: 2020/04/21 16:14:43 Channel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:14:43 Subchannel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:14:43 [xds-client 0xc00011a870] Shutdown
INFO: 2020/04/21 16:14:43 [xds-resolver 0xc000203900] Shutdown
WARNING: 2020/04/21 16:14:43 [xds-client 0xc00011a870] ADS stream is closed with error: rpc error: code = Canceled desc = context canceled
INFO: 2020/04/21 16:14:43 transport: loopyWriter.run returning. connection error: desc = "transport is closing"
INFO: 2020/04/21 16:14:43 [cds-lb 0xc000258750] Watch cancelled on resource name be-srv-cluster with xds-client 0xc00011a870
INFO: 2020/04/21 16:14:43 Subchannel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:14:43 [eds-lb 0xc000258820] Watch cancelled on resource name be-srv-cluster with xds-client 0xc00011a870
```

### xDS Server rotate endpoint

```bash
INFO[0070] >>>>>>>>>>>>>>>>>>> creating ENDPOINT for remoteHost:port be.cluster.local:50052
INFO[0070] >>>>>>>>>>>>>>>>>>> creating CLUSTER be-srv-cluster
INFO[0070] >>>>>>>>>>>>>>>>>>> creating RDS be-srv-vs
INFO[0070] >>>>>>>>>>>>>>>>>>> creating LISTENER be-srv
INFO[0070] >>>>>>>>>>>>>>>>>>> creating snapshot Version 2
```

### gRPC Server Call #2
```log
$ go run src/grpc_client.go --host xds-experimental:///be-srv

INFO: 2020/04/21 16:16:08 parsed scheme: "xds-experimental"
INFO: 2020/04/21 16:16:08 [xds-bootstrap] Got bootstrap file location from GRPC_XDS_BOOTSTRAP environment variable: /home/srashid/Desktop/xds_grpc/app/xds_bootstrap.json
INFO: 2020/04/21 16:16:08 [xds-bootstrap] Bootstrap content: {
  "xds_servers": [
    {
      "server_uri": "xds.domain.com:18000"
    }
  ],
  "node": {
    "id": "b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>",
    "metadata": {
      "R_GCP_PROJECT_NUMBER": "123456789012"
    },
    "locality": {
      "zone": "us-central1-a"
    }
  }
}
INFO: 2020/04/21 16:16:08 [xds-bootstrap] Bootstrap config for creating xds-client: &{BalancerName:xds.domain.com:18000 Creds:<nil> NodeProto:id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" }
INFO: 2020/04/21 16:16:08 [xds-resolver 0xc00022b900] Creating resolver for target: {Scheme:xds-experimental Authority: Endpoint:be-srv}
WARNING: 2020/04/21 16:16:08 [xds-resolver 0xc00022b900] No credentials available, using Insecure
INFO: 2020/04/21 16:16:08 parsed scheme: ""
INFO: 2020/04/21 16:16:08 scheme "" not registered, fallback to default scheme
INFO: 2020/04/21 16:16:08 ccResolverWrapper: sending update to cc: {[{xds.domain.com:18000  <nil> 0 <nil>}] <nil> <nil>}
INFO: 2020/04/21 16:16:08 ClientConn switching balancer to "pick_first"
INFO: 2020/04/21 16:16:08 Channel switches to new LB policy "pick_first"
INFO: 2020/04/21 16:16:08 Subchannel Connectivity change to CONNECTING
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Created ClientConn to xDS server: xds.domain.com:18000
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Created
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.Listener, resource names: [be-srv]
INFO: 2020/04/21 16:16:08 [xds-resolver 0xc00022b900] Watch started on resource name be-srv with xds-client 0xc000136870
INFO: 2020/04/21 16:16:08 Subchannel picks a new address "xds.domain.com:18000" to connect
INFO: 2020/04/21 16:16:08 pickfirstBalancer: HandleSubConnStateChange: 0xc0002780f0, {CONNECTING <nil>}
INFO: 2020/04/21 16:16:08 Channel Connectivity change to CONNECTING
INFO: 2020/04/21 16:16:08 Subchannel Connectivity change to READY
INFO: 2020/04/21 16:16:08 pickfirstBalancer: HandleSubConnStateChange: 0xc0002780f0, {READY <nil>}
INFO: 2020/04/21 16:16:08 Channel Connectivity change to READY
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS stream created
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv" type_url:"type.googleapis.com/envoy.api.v2.Listener"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received, type: type.googleapis.com/envoy.api.v2.Listener
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received: version_info:"2" resources:<type_url:"type.googleapis.com/envoy.api.v2.Listener" value:"\n\006be-srv\232\001z\nx\n`type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager\022\024\032\022\n\002\032\000\022\014be-srv-route" > type_url:"type.googleapis.com/envoy.api.v2.Listener" nonce:"1"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name: be-srv, type: *envoy_api_v2.Listener, contains: name:"be-srv" api_listener:<api_listener:<type_url:"type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager" value:"\032\022\n\002\032\000\022\014be-srv-route" > >
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with type *envoy_config_filter_network_http_connection_manager_v2.HttpConnectionManager, contains rds:<config_source:<ads:<> > route_config_name:"be-srv-route" >
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] xds: client received LDS update: {routeName:be-srv-route}, err: <nil>
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.RouteConfiguration, resource names: [be-srv-route]
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.Listener, version: 2, nonce: 1
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-route" type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: version_info:"2" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv" type_url:"type.googleapis.com/envoy.api.v2.Listener" response_nonce:"1"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received, type: type.googleapis.com/envoy.api.v2.RouteConfiguration
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received: version_info:"2" resources:<type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" value:"\n\014be-srv-route\022+\n\tbe-srv-vs\022\006be-srv\032\026\n\002\n\000\022\020\n\016be-srv-cluster" > type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" nonce:"2"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name: be-srv-route, type: *envoy_api_v2.RouteConfiguration, contains: name:"be-srv-route" virtual_hosts:<name:"be-srv-vs" domains:"be-srv" routes:<match:<prefix:"" > route:<cluster:"be-srv-cluster" > > >
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name be-srv-route, type string, value be-srv-cluster added to cache
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] xds: client received RDS update: {clusterName:be-srv-cluster}, err: <nil>
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.RouteConfiguration, version: 2, nonce: 2
INFO: 2020/04/21 16:16:08 [xds-resolver 0xc00022b900] Received update on resource be-srv from xds-client 0xc000136870, generated service config: {
    "loadBalancingConfig":[
      {
        "cds_experimental":{
          "Cluster": "be-srv-cluster"
        }
      }
    ]
  }
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: version_info:"2" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-route" type_url:"type.googleapis.com/envoy.api.v2.RouteConfiguration" response_nonce:"2"
INFO: 2020/04/21 16:16:08 ccResolverWrapper: sending update to cc: {[] 0xc0003d2160 0xc0003de018}
INFO: 2020/04/21 16:16:08 ClientConn switching balancer to "cds_experimental"
INFO: 2020/04/21 16:16:08 Channel switches to new LB policy "cds_experimental"
INFO: 2020/04/21 16:16:08 [cds-lb 0xc0003e00d0] Created
INFO: 2020/04/21 16:16:08 [cds-lb 0xc0003e00d0] Receive update from resolver, balancer config: &{LoadBalancingConfig:<nil> ClusterName:be-srv-cluster}
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.Cluster, resource names: [be-srv-cluster]
INFO: 2020/04/21 16:16:08 [cds-lb 0xc0003e00d0] Watch started on resource name be-srv-cluster with xds-client 0xc000136870
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.Cluster"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received, type: type.googleapis.com/envoy.api.v2.Cluster
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received: version_info:"2" resources:<type_url:"type.googleapis.com/envoy.api.v2.Cluster" value:"\n\016be-srv-cluster\032\004\n\002\032\000\020\003" > type_url:"type.googleapis.com/envoy.api.v2.Cluster" nonce:"3"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name: be-srv-cluster, type: *envoy_api_v2.Cluster, contains: name:"be-srv-cluster" type:EDS eds_cluster_config:<eds_config:<ads:<> > >
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name be-srv-cluster, type client.CDSUpdate, value {ServiceName:be-srv-cluster EnableLRS:false} added to cache
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.Cluster, version: 2, nonce: 3
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: version_info:"2" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.Cluster" response_nonce:"3"
INFO: 2020/04/21 16:16:08 [cds-lb 0xc0003e00d0] Watch update from xds-client 0xc000136870, content: {ServiceName:be-srv-cluster EnableLRS:false}
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Created
INFO: 2020/04/21 16:16:08 [cds-lb 0xc0003e00d0] Created child policy 0xc000143ee0 of type eds_experimental
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Receive update from resolver, balancer config: &{LoadBalancingConfig:<nil> BalancerName: ChildPolicy:<nil> FallBackPolicy:<nil> EDSServiceName:be-srv-cluster LrsLoadReportingServerName:<nil>}
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ADS request for new watch of type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment, resource names: [be-srv-cluster]
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Watch started on resource name be-srv-cluster with xds-client 0xc000136870
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received, type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS response received: version_info:"2" resources:<type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" value:"\n\016be-srv-cluster\022C\n\034\n\013us-central1\022\rus-central1-a\022\036\020\001\n\032\n\030\n\026\022\020be.cluster.local\030\204\207\003\032\003\010\350\007" > type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" nonce:"4"
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Resource with name: be-srv-cluster, type: *envoy_api_v2.ClusterLoadAssignment, contains: cluster_name:"be-srv-cluster" endpoints:<locality:<region:"us-central1" zone:"us-central1-a" > lb_endpoints:<endpoint:<address:<socket_address:<address:"be.cluster.local" port_value:50052 > > > health_status:HEALTHY > load_balancing_weight:<value:1000 > >
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Watch update from xds-client 0xc000136870, content: &{Drops:[] Localities:[{Endpoints:[{Address:be.cluster.local:50052 HealthStatus:1 Weight:0}] ID:us-central1-us-central1-a- Priority:0 Weight:1000}]}
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] Sending ACK for response type: type.googleapis.com/envoy.api.v2.ClusterLoadAssignment, version: 2, nonce: 4
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] New priority 0 added
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] New locality us-central1-us-central1-a- added
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Switching priority from unset to 0
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Created child policy 0xc000248960 of type round_robin
INFO: 2020/04/21 16:16:08 base.baseBalancer: got new ClientConn state:  {{[{be.cluster.local:50052  <nil> 0 <nil>}] <nil> <nil>} <nil>}
INFO: 2020/04/21 16:16:08 [xds-client 0xc000136870] ADS request sent: version_info:"2" node:<id:"b7f9c818-fb46-43ca-8662-d3bdbcf7ec18~<IP_ADDRESS>" metadata:<fields:<key:"R_GCP_PROJECT_NUMBER" value:<string_value:"123456789012" > > > locality:<zone:"us-central1-a" > build_version:"gRPC Go 1.28.1" user_agent_name:"gRPC Go" user_agent_version:"1.28.1" client_features:"envoy.lb.does_not_support_overprovisioning" > resource_names:"be-srv-cluster" type_url:"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment" response_nonce:"4"
INFO: 2020/04/21 16:16:08 Subchannel Connectivity change to CONNECTING
INFO: 2020/04/21 16:16:08 Subchannel picks a new address "be.cluster.local:50052" to connect
INFO: 2020/04/21 16:16:08 base.baseBalancer: handle SubConn state change: 0xc000278ad0, CONNECTING
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Balancer state update from locality us-central1-us-central1-a-, new state: {ConnectivityState:CONNECTING Picker:0xc000278a80}
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Child pickers with weight: map[us-central1-us-central1-a-:weight:1000,picker:0xc0003d9e00,state:CONNECTING]
INFO: 2020/04/21 16:16:08 Channel Connectivity change to CONNECTING
INFO: 2020/04/21 16:16:08 Subchannel Connectivity change to READY
INFO: 2020/04/21 16:16:08 base.baseBalancer: handle SubConn state change: 0xc000278ad0, READY
INFO: 2020/04/21 16:16:08 roundrobinPicker: newPicker called with info: {map[0xc000278ad0:{{be.cluster.local:50052  <nil> 0 <nil>}}]}
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Balancer state update from locality us-central1-us-central1-a-, new state: {ConnectivityState:READY Picker:0xc00027b5f0}
INFO: 2020/04/21 16:16:08 [eds-lb 0xc000143ee0] Child pickers with weight: map[us-central1-us-central1-a-:weight:1000,picker:0xc00027f220,state:READY]
INFO: 2020/04/21 16:16:08 Channel Connectivity change to READY
2020/04/21 16:16:09 RPC Response: 0 message:"Hello unary RPC msg   from hostname srashid1"
INFO: 2020/04/21 16:16:09 Channel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:16:09 [xds-resolver 0xc00022b900] Watch cancel on resource name be-srv with xds-client 0xc000136870
INFO: 2020/04/21 16:16:09 Channel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:16:09 Subchannel Connectivity change to SHUTDOWN
INFO: 2020/04/21 16:16:09 [xds-client 0xc000136870] Shutdown
INFO: 2020/04/21 16:16:09 [xds-resolver 0xc00022b900] Shutdown
WARNING: 2020/04/21 16:16:09 [xds-client 0xc000136870] ADS stream is closed with error: rpc error: code = Canceled desc = context canceled
INFO: 2020/04/21 16:16:09 Subchannel Connectivity change to SHUTDOWN
```


text:
Builds upon [HGM V22](HGMv22.md)'s option A.

# HGM V22's Problem

It isn't a problem per se, but it's an unfortunate bit of overhead that HGM globally puts on the system, even when HGM isn't used. It makes it not a zero-cost abstraction.

Specifically, a borrow ref in HGM is four things:

* Pointer to the object
* Offset to the generation
* Remembered generation
* Scope tether bit mask

When we use a borrow ref to get a struct's inline member, we need to:

* Add to the object pointer
* Subtract from the generation offset
* (Do nothing to remembered generation)
* Shift the bit mask

That's normally fine, except **it also happens for immutable region references** because when a pure function returns a borrow ref, it has to have all that information if it's to be a real borrow reference. And unfortunately, none of these can be calculated from any others.

In other words, HGM's overhead is also present when we're doing immutable region borrowing.

It's not a dealbreaker... in the hands of a master, if HGM is used enough, it could be worth it. But we shouldn't need to be a master to take advantage of Vale's speeds.

# Solution

Let's take a few steps backwards. Let's opt-in to tethering per-type (or even per-coord, worth considering) with a `tetherable` keyword on the struct:

```
struct Spaceship tetherable {
  engine Engine;
}
```

And then we can have `live` references to it.

`tetherable` means that we'll always have some bytes before the instance where we can find its scope tether, which is either a 2-byte RC or a scope tether.

If the object already has a generation (such as if it's a stack allocation, heap allocation, or array element, inline varying struct with owning ref, inline enum) this won't cost us anything. It will otherwise cost us some space for some inline structs though, which is unfortunate.

This could fit pretty well though. It's pretty likely that most tethering will happen on arrays (for ECS) and on top level denizens (in OO) so it might work out well.

repository: Verdagon/Vale

branch_name: refs/heads/master

extension: md

gha_language: Scala

license_type: permissive

repo_name: Verdagon/Vale


text:
References
==========

The Sdb databases uses a reference counting system to identify which Sdb instances must be freed from the namespaces (SdbNs). When you create a new instance it comes with the reference counter variable set to 1. And everytime you add a new reference to it from another place it will increase that counter. In the most common case that would not be used, see the following example:

	Sdb* s = sdb_new (NULL, NULL, 0);
	sdb_free (s);

The first line increments the internal reference counting by 1 and the second substracts one, if it's 0 then proceeds with the freeing stuff.

That's not really useful in this situation but we may probably fall into issues when associating independent instances in a different namespace with `sdb_ns`.

The second scenario will look like this:

	Sdb* s = sdb_new0 ();   // s->refs = 1
	Sdb* r = sdb_new0 ();   // r->refs = 1
	sdb_ns_set (s, "r", r); // r->refs = 2
	sdb_free (s);           // s->refs = 0 r->refs = 1
	sdb_free (r);           // s->refs = 0

Most common sdb namespace usage (without referencing other databases doesnt requires refcounting:

	Sdb* s = sdb_new0 ();
	Sdb* r = sdb_ns (s, "r");
	sdb_free (s);

In the case we are using a copy of the pointer we will need to use `sdb_drain` to transplant the information to make persistent pointers for new databases. This method allows backreferences to keep working as expected even if used by namespaces referencing other databases.

This was a complex explanation, so i'll try to show you an usage example that demonstrates where `sdb_drain` is useful.

	Sdb* s = sdb_new0 ();
	Sdb* r = s;
	sdb_drain (s, sdb_new0 ());
	sdb_const_get (r, "key", 0);

What it's happening here is the following:

1. Create a new sdb instance
2. Create a reference to this one
3. We drain a new database into 's' storage
4. We can still use the old pointer with the new database

The `sdb_drain` call is updating the internals of the database by deinitializing the old one and copying the contents of another one inside the original allocation.

When this call is performed the reference counting is kept from the old instance, so we keep track of the old references. In the case we are using a weak reference like `Sdb* r = s` we should not free that reference unless we do an sdb_ref() on it.

license: MIT

repository: ratijas/sdb

gha_license_id: MIT

repo_name: ratijas/sdb


text:
---
hrs_structure:
  division: '3'
  volume: '12'
  title: '28'
  chapter: 514A
  section: 514A-41
type: hrs_section
tags:
  - Property
  - Family
menu:
  hrs:
    identifier: HRS_0514A-0041
    parent: HRS0514A
    name: 514A-41 Supplementary public report
weight: 32195
title: Supplementary public report
full_title: 514A-41 Supplementary public report
---
**§514A-41 Supplementary public report.** (a) If after the effective date has been issued by the commission for a public report, any circumstance occurs which would render the public report misleading as to purchasers in any material respect, the developer shall stop all offers of sale and sales and immediately submit to the commission a supplementary public report, together with such supporting information as may be required by the commission, to update the information contained in the public report, accompanied by a nonrefundable fee as provided in rules adopted by the director of commerce and consumer affairs pursuant to chapter 91\. Offers of sale and sales shall not resume until an effective date has been issued by the commission for the supplementary public report. The developer shall provide all prospective purchasers with a true copy of the supplementary public report and all prior public reports not superseded by the supplementary public report.

(b) The commission may determine when a supplementary public report will supersede the public reports previously issued for the project.

(c) Notwithstanding the provisions of this section, the rescission rights, if any, of a purchaser shall be governed exclusively by sections 514A-62 and 514A-63\. This does not preclude a purchaser from exercising any rescission rights pursuant to a contract for sale or any applicable common law remedies.

(d) Notwithstanding any other provision to the contrary, this section shall not apply to a time share project duly registered under chapter 514E if, with regard to that time share project:

(1) A copy of the disclosure statement required by chapter 514E is required to be delivered to the purchaser or prospective purchaser; or

(2) Pursuant to section 514E-30, a copy of the disclosure statement required by chapter 514E is not required to be delivered to the purchaser or prospective purchaser because the offer and sale of the time share interest is made outside of Hawaii. [L 1977, c 98, pt of §2; am L 1984, c 58, §1; am L 1986, c 295, §3; am L 1991, c 44, §11; am L 1992, c 173, §1; am L 2001, c 237, §2; am L 2002, c 204, §3]

repository: SamMade/BlueAndKrabby

repo_name: SamMade/BlueAndKrabby


text:
## (Section: Nodetool) - Nodetool usage

*
```bash
     usage: nodetool [(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]
          [(-u <username> | --username <username>)]
          [(-pw <password> | --password <password>)] [(-h <host> | --host <host>)]
          [(-p <port> | --port <port>)] <command> [<args>]
```

## (Section: Nodetool) -  Nodetool commands

```bash
     The most commonly used nodetool commands are:
     assassinate                  Forcefully remove a dead node without re-replicating any data.  Use as a last resort if you cannot removenode
     bootstrap                    Monitor/manage node-s bootstrap process
     cleanup                      Triggers the immediate cleanup of keys no longer belonging to a node. By default, clean all keyspaces
     clearsnapshot                Remove the snapshot with the given name from the given keyspaces. If no snapshotName is specified we will remove all snapshots
     compact                      Force a (major) compaction on one or more tables or user-defined compaction on given SSTables
     compactionhistory            Print history of compaction
     compactionstats              Print statistics on compactions
     decommission                 Decommission the *node I am connecting to*
     describecluster              Print the name, snitch, partitioner and schema version of a cluster
     describering                 Shows the token ranges info of a given keyspace
     disableautocompaction        Disable autocompaction for the given keyspace and table
     disablebackup                Disable incremental backup
     disablebinary                Disable native transport (binary protocol)
     disablegossip                Disable gossip (effectively marking the node down)
     disablehandoff               Disable storing hinted handoffs
     disablehintsfordc            Disable hints for a data center
     disablethrift                Disable thrift server
     drain                        Drain the node (stop accepting writes and flush all tables)
     enableautocompaction         Enable autocompaction for the given keyspace and table
     enablebackup                 Enable incremental backup
     enablebinary                 Reenable native transport (binary protocol)
     enablegossip                 Reenable gossip
     enablehandoff                Reenable future hints storing on the current node
     enablehintsfordc             Enable hints for a data center that was previsouly disabled
     enablethrift                 Reenable thrift server
     failuredetector              Shows the failure detector information for the cluster
     flush                        Flush one or more tables
     garbagecollect               Remove deleted data from one or more tables
     gcstats                      Print GC Statistics
     getcompactionthreshold       Print min and max compaction thresholds for a given table
     getcompactionthroughput      Print the MB/s throughput cap for compaction in the system
     getconcurrentcompactors      Get the number of concurrent compactors in the system.
     getendpoints                 Print the end points that owns the key
     getinterdcstreamthroughput   Print the Mb/s throughput cap for inter-datacenter streaming in the system
     getlogginglevels             Get the runtime logging levels
     getsstables                  Print the sstable filenames that own the key
     getstreamthroughput          Print the Mb/s throughput cap for streaming in the system
     gettimeout                   Print the timeout of the given type in ms
     gettraceprobability          Print the current trace probability value
     gossipinfo                   Shows the gossip information for the cluster
     help                         Display help information
     info                         Print node information (uptime, load, ...)
     invalidatecountercache       Invalidate the counter cache
     invalidatekeycache           Invalidate the key cache
     invalidaterowcache           Invalidate the row cache
     join                         Join the ring
     listsnapshots                Lists all the snapshots along with the size on disk and true size.
     move                         Move node on the token ring to a new token
     netstats                     Print network information on provided host (connecting node by default)
     pausehandoff                 Pause hints delivery process
     proxyhistograms              Print statistic histograms for network operations
     rangekeysample               Shows the sampled keys held across all keyspaces
     rebuild                      Rebuild data by streaming from other nodes (similarly to bootstrap)
     rebuild_index                A full rebuild of native secondary indexes for a given table
     refresh                      Load newly placed SSTables to the system without restart
     refreshsizeestimates         Refresh system.size_estimates
     reloadlocalschema            Reload local node schema from system tables
     reloadtriggers               Reload trigger classes
     relocatesstables             Relocates sstables to the correct disk
     removenode                   Show status of current node removal, force completion of pending removal or remove provided ID
     repair                       Repair one or more tables
     replaybatchlog               Kick off batchlog replay and wait for finish
     resetlocalschema             Reset node=s local schema and resync
     resumehandoff                Resume hints delivery process
     ring                         Print information about the token ring
     scrub                        Scrub (rebuild sstables for) one or more tables
     setcachecapacity             Set global key, row, and counter cache capacities (in MB units)
     setcachekeystosave           Set number of keys saved by each cache for faster post-restart warmup. 0 to disable
     setcompactionthreshold       Set min and max compaction thresholds for a given table
     setcompactionthroughput      Set the MB/s throughput cap for compaction in the system, or 0 to disable throttling
     setconcurrentcompactors      Set number of concurrent compactors in the system.
     sethintedhandoffthrottlekb   Set hinted handoff throttle in kb per second, per delivery thread.
     setinterdcstreamthroughput   Set the Mb/s throughput cap for inter-datacenter streaming in the system, or 0 to disable throttling
     setlogginglevel              Set the log level threshold for a given class. If both class and level are empty/null, it will reset to the initial configuration
     setstreamthroughput          Set the Mb/s throughput cap for streaming in the system, or 0 to disable throttling
     settimeout                   Set the specified timeout in ms, or 0 to disable timeout
     settraceprobability          Sets the probability for tracing any given request to value. 0 disables, 1 enables for all requests, 0 is the default
     snapshot                     Take a snapshot of specified keyspaces or a snapshot of the specified table
     status                       Print cluster information (state, load, IDs, ...)
     statusbackup                 Status of incremental backup
     statusbinary                 Status of native transport (binary protocol)
     statusgossip                 Status of gossip
     statushandoff                Status of storing future hints on the current node
     statusthrift                 Status of thrift server
     stop                         Stop compaction
     stopdaemon                   Stop cassandra daemon
     tablehistograms              Print statistic histograms for a given table
     tablestats                   Print statistics on tables
     toppartitions                Sample and print the most active partitions for a given column family
     tpstats                      Print usage statistics of thread pools
     truncatehints                Truncate all hints on the local node, or truncate hints for the endpoint(s) specified.
     upgradesstables              Rewrite sstables (for the requested tables) that are not on the current version (thus upgrading them to said current version)
     verify                       Verify (check data checksum for) one or more tables
     version                      Print cassandra version
     viewbuildstatus              Show progress of a materialized view build

     See "nodetool help <command>" for more information on a specific command.
```

gha_language: Shell


text:
# Telegram Mensa Bot

This bot for telegram allows you to receive your canteen's meal plan using the great OpenMensa-API.

# Technology Stack

- Open Mensa API
- Telegraf (Telegram Bot Library)

# Development

Please install pre-commit to format everything correctly:

1. `pip install pre-commit`
2. `pre-commit install`

repository: vigonotion/telegram-mensa-bot

gha_language: JavaScript

repo_name: vigonotion/telegram-mensa-bot


text:
> https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

- 和121一样，求股票收益最大
- 但是允许多次买入卖出，但是同一时间最多持有一个股票
- 股票是升降的，只要在波谷买入，波峰卖出，即可赚钱

- 方法一
  - 一个循环，先找出一个波谷，再找出一个波峰
  - 因为需要先买入，所以先找波谷

```go
func maxProfit(prices []int) int {
	i := 0
	_max := 0
	_min := 0
	m := 0
	for i < len(prices)-1 {
		for i < len(prices)-1 && prices[i] >= prices[i+1] {
			i++
		}
		_min = prices[i]

		for i < len(prices)-1 && prices[i] <= prices[i+1] {
			i++
		}
		_max = prices[i]

		m += _max - _min
	}

	return m
}
```

- 方法二
  - 和方法一的思想是一致的
  - 想想一下求积分的那个阶梯

```go
func maxProfit(prices []int) int {
	i := 0
	m := 0
	for i < len(prices)-1 {
		cha := prices[i+1] - prices[i]
		if cha > 0 {
			m += cha
		}
		i++
	}

	return m
}
```

repository: saurabhdhupar/notes

repo_name: saurabhdhupar/notes


text:
# Shorthand attributes
It's not uncommon to have an attribute where the name and value are the same, like src={src}.
```
<script>
	let src = 'tutorial/image.gif';
	let alt = 'ginger man'
</script>

<img {src} {alt}>
```

Svelte automatically updates the DOM when your component's state changes.

branch_name: refs/heads/main


text:
## Laravel's Eloquent ORM Bootstrapped for Concrete 5.7

This simple package is used to add the ability to create Eloquent Model's within Concrete5. This is a developer package only, there is no fun UI at this time.

Requirements

- Concrete 5.7.4+
- PHP 5.5+

For Concrete 5.6, please see this branch:
(repo coming soon)

Instructions

Download zip file from github and extract to your Concrete5 ROOT directory, your structure should look like this:
```
application
...
packages/eloquent
```

Go to Concrete5 Dashboard and Install Package

Useage

Any new 5.7 package can automatically utilize and autoload your new eloquent models now if placed within the src/Models folder of your package. Example:
```
www/packages/my_package/src/Models/User.php
```

An example C5 User model then looks like this:
```
namespace Concrete\Package\MyPackage\Src\Models;
defined('C5_EXECUTE') or die("Access Denied.");

use Illuminate\Database\Eloquent\Model as EloquentModel;

class C5User Extends EloquentModel{

    protected $table = 'Users';
    protected $fillable = [];
    protected $primaryKey = 'uID';
    public $timestamps = false;

    public function getUserID()
    {
        return $this->uID;
    }

}
```


text:
<!--- SPDX-License-Identifier: Apache-2.0 -->

# Type annotations for ONNX

At Facebook, we work with community best practices to ensure high code quality, readability and reliability. In line with this, we just added type annotations to our python code to help ONNX developers more easily contribute to the project.

These type annotations are used by [mypy](https://github.com/python/mypy) within the ONNX CI systems to ensure a continuously high code quality standard.
We also have type annotations for our APIs, which means your tools built on top of the ONNX APIs can use static analysis tools like mypy to ensure they are using the APIs correctly.

We expect this to have a positive impact on the reliability of ONNX and dependent projects like ONNX converters - we've also found and fixed a few bugs thanks to the addition of type annotations.

## What is mypy?
Mypy is an opt-in type checker. Annotations are optional and, if present, will be used for static type checking. While it is not advisable to rely too much on mypy to find all errors (for programmers used to a static type system like in C++, it's often confusing that mypy doesn't find some very obvious typing errors), it is still very helpful given the errors it does find.

## Using the type annotations in dependent projects
Say, for example, you're building a converter for ONNX, which converts between ONNX models and the models of some machine learning framework. If you use mypy for your project, it will automatically detect the type hints in the ONNX code and use them to check that you read from and wrote to the ONNX model correctly. Doing this will notify you about identifier typos or wrong data types when accessing attributes of the ONNX protocol buffer or other ONNX features.

## For ONNX contributors
If you're contributing to the ONNX repository, you need to add type annotations to your project or CI will fail. Here is how to install it:

#### Python 3
If you're using Python 3, you can simply install mypy as an extra dependency of onnx.

Call from the top level directory of your onnx repository:

    ~/onnx $ pip install -e .[mypy]

And then run the type checks:

    ~/onnx $ python setup.py typecheck

#### Python 2
The mypy type checker needs python 3 to run (even though it can check python 2 code), so if your onnx development environment is set up with python 2, you need to install mypy into your system python 3 packages (i.e. not into your python 2 virtualenv):

    $ pip3 install mypy

Running then works as it does above for python 3.

    ~/onnx $ python setup.py typecheck

Since you've installed mypy manually, you won't get updates for it when we change the version of the mypy dependency in setup.py, so if you're seeing a CI error and can't reproduce it locally, check your mypy version.

### What should I annotate?

Type annotations are (usually) only needed for function arguments and return types, mypy will infer local variable types automatically. "Usually" means there are a few exceptions, but mypy will report these if you hit them.

### What do type annotations look like?
We can't use PEP484 annotations, because we have to support python 2. So we're writing our type annotations in comments. Typed code looks like this:

    def myfunc(arg):  # type: (int) -> bool
      return arg == 2

    class MyClass(object):
      def __init__(self):  # type: () -> None
        pass

      def myfunc(self, arg):  # type: (int) -> bool
        return arg == 2

      # Alternative notation for many parameters
      def myfunc(
        arg1,  # type: int
        arg2,  # type: int
      ):  # type: (...) -> bool
        return arg1 == arg2

repository: AlexandreEichenberger/onnx

repo_name: AlexandreEichenberger/onnx


text:
---
title: Serve Static Assets (using the Mux Router)
author: Edd Turtle
type: post
date: 2016-05-22T11:54:24+00:00
url: /serve-static-assets-using-the-mux-router/
categories:
  - Uncategorized
tags:
  - assets
  - css
  - dir
  - file
  - handler
  - images
  - img
  - js
  - mux
  - router
  - serve
  - server
  - static
meta_image: 2016/static-assets.png
---
Using a router is great when passing off incoming requests to functions to handle and return data. Often though, you just want to serve an entire directory and make everything inside it public. This is useful for images, styles and javascript.

In this example we're using the [Gorilla mux router](https://github.com/gorilla/mux) ("HTTP request multiplexer") and we have setup a new route for the entire directory. We're using `static` as the folder name to serve, which we pass to our `FileServer()` as a new route on the router.

```go
package main

import (
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	router := NewRouter()
	if err := http.ListenAndServe(":8080", router); err != nil {
		log.Fatal("ListenAndServe Error: ", err)
	}
}

func NewRouter() *mux.Router {
	router := mux.NewRouter().StrictSlash(true)

	// Choose the folder to serve
	staticDir := "/static/"

	// Create the route
	router.
		PathPrefix(staticDir).
		Handler(http.StripPrefix(staticDir, http.FileServer(http.Dir("."+staticDir))))

	return router
}
```

![serve static assets](/img/2016/static-assets.png)

### Without gorilla/mux

Although this post is tailored towards when you are using the gorilla mux router, it's also good to know how to do it the default stdlib way (it's actually very similar). The code below should result in the same out come as the example above.

```go
package main

import (
	"log"
	"net/http"
)

func main() {

	staticDir := "/static/"
	http.Handle(staticDir, http.StripPrefix(staticDir, http.FileServer(http.Dir("."+staticDir))))

	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("ListenAndServe Error: ", err)
	}
}
```


text:
# Clavicybe avellaneoalba (Murrill) Harmaja, 2002 SPECIES

#### Status
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Karstenia 42(2): 42 (2002)

#### Original name
Clitocybe avellaneoalba Murrill, 1913

### Remarks
null

repository: mdoering/backbone

path: /life/Fungi/Basidiomycota/Agaricomycetes/Agaricales/Hygrophoraceae/Ampulloclitocybe/Ampulloclitocybe avellaneoalba/ Syn. Clavicybe avellaneoalba/README.md

repo_name: mdoering/backbone


text:
python-inject changes
=====================

### 5.0.0 (2023-06-10)
- Support for PEP0604 for Python>=3.10.

### 4.3.1 (2020-08-17)
- Use assertRaisesRegex instead of assertRaisesRegexp to fix deprecation warnings.

### 4.3.0 (2020-08-11)
- Support for classes in autoparams, #59.
- Support for asyncio, #66.

### 4.2.0 (2020-05-15)
- Migrated autoparams and annotations to typing.get_type_hints.
- Fix boolean casting to make possible to inject DataFrame (#55) #56.
- Add support for forward references #54.

### 4.1.2 (2020-04-13)
- Include py.typed and manifest in dist, #50.

### 4.1.1 (2020-02-25)
- UTF8 encoding for readme in setup.py, #48.

### 4.1.0 (2020-02-24)
- More precise typing #47.
- Removed Python 3.5 support.

### 4.0.0 (2019-11-25)
- Drop Python <3.5 support.
- [feature] Add typed information, #43.
- [chore] Remov old typing information as it is no longer relevant for v4.0.0, #43.

### 3.5.4 (2019-07-30)
- MyPy compatibility #36.

### 3.5.3 (2019-07-24)
- AttributeError: type object 'Callable' has no attribute '_abc_registry' #34

### 3.5.2 (2019-07-10)
- Modify type-hints to support Hashable bindings and other improvements,  #33.
- Merge these type-hints into the .py file instead of having a .pyi file, #33.

### 3.5.1 (2019-04-16)
- Export Binder and Injector in pyi, #29.
- Make autoparams work with keyword-only parameters, #26.

### 3.5.0 (2019-03-11)
- Configurable auto-initialization, #23
  [@Fedorof](https://github.com/Fedorof).

### 3.4.0 (2018-08-01)
- Type hinting in Python 3, #20
  [@Enforcer](https://github.com/Enforcer).
- Autoparams leveraging types annotations, #21
  [@Enforcer](https://github.com/Enforcer).

### 3.3.2 (2017-09-14)
- Use getfullargspec when executing in Python3, #17
  [@jaimewyant](https://github.com/jaimewyant).

### 3.3.1 (2015-03-28)
- Fixed race condition in bind_to_constructor, #14
  [@peick](https://github.com/peick).

### 3.3.0 (2014-08-22)
- Added `inject.params(arg1=cls1, arg2=cls2)`, deprecated `inject.param`, #12
  (thanks [@scharf](https://github.com/scharf)).

### 3.2.0 (2014-08-04)
- Added `inject.configure_once` and `inject.is_configured`, #11.

### 3.1.1 (2014-03-14)
- Switch from root logger to module logger, #8.

### 3.1.0 (2014-03-07)
- `inject.param` decorator.
- Small fixes in exceptions.

### 3.0.0 (2014-02-10)
- Smaller, better, faster version with simpler and cleaner API.

### 2.0.0-alpha1 (2010-08-25)
- Second version (never made it to stable).

### 1.0.0 (2010-02-12)
- Initial release.

repository: ivankorobkov/python-inject

gha_language: Python

repo_name: ivankorobkov/python-inject


text:
faat-figpy package
==================

This package enables you to easily read python files as configuration.

Python is an elegant way of expressing configuration.
This package facilitates the reading those files in your script.
Define the symbols you want to keep in UPPER_CASE and all the others are ignored as they are loaded into a settings object.

For example code, the following code defines values for USERNAME, DOMAIN, and LOGPATH.

```python
USERNAME =<EMAIL_ADDRESS>DOMAIN = 'example.com'
LOG_PATH = '/var/log/my-app/app.log'
```

But because this is python code, not just a simple configuration language, a more advanced deployment could read these settings from elsewhere.

```python
import os
here = os.path.dirname(__file__)

USERNAME =<EMAIL_ADDRESS>DOMAIN = os.environ['example.com']
LOG_PATH = os.path.join(here, 'log.txt')
```

The configuration can be loaded and used as follows.

```python
import faat.figpy

settings = faat.figpy.load("/path/to/app.conf", requires=["USERNAME", "DOMAIN"])
print(settings.USERNAME)
print(settings["DOMAIN"])
```

If using `argparse`, the configuration can be loaded directly.

```python
import argparse
import faat.figpy

parser = argparse.ArgumentParser(description="Does something cool")
parser.add_argument("config", type=faat.figpy.config_arg)
args = parser.parse_args()

print(args.config.API_URL)
```


text:
# Signer

Signer is a simple token generation scheme using `xchacha20poly1305`. It generates an authenticated
and encrypted token which can be decrypted and verified by the same key. Signer is basically "Branca"
without the crufty base32 and 32-bit binary time field. It uses url-safe base64 encoding.

The Token type is a byte slice implementing base64 MarshalText and UnmarshalText.

# Use Case

You have a server that wants to give clients a token. The server need to be able to verify
that the token it issued came from the server (via the same key) and that this token was
not modified by the client or some other party. The server also wants to keep the information
inside the token private, and only accessible by the server or other parties in possession of
the key. The authentication is symmetric. Only servers in possesion of the key can verify the
token's authenticity.

You should not use Signer if the client (not just the server) needs to read and/or authenticate the token
E.G., asymmetric authentication with RSA or an elliptic curve. This token is for servers that issue
tokens, perhaps for sessions or other data.

For example: If you are using JWT with HMAC (and/or encryption), you can replace it with signer.
If you are using JWT with RSA/EC, you can not.

# Wire Format

Below is the Token's wire format:
```
	version[1] nonce[24] ciphertext[...] tag[16] | base64

	The first 1+24 bytes are the header, authenticated by the AEAD, but not encrypted.
	The version is fixed to 0x41 (A)
	The nonce is a randomly-generated 24-byte string

	The rest is the output of the AEAD, the ciphertext and 16 byte tag.
	The ciphertext is the encrypted msg.
	The tag is a message authentication code (MAC) used to verify the integrity of the header and ciphertext

	Finally, the vertical bar denotes the Token's intended string encoding is base64 (url-safe)
```

# Interface (caller defined)
```go
type Signer interface{
	// Sign creates a token using the msg and nonce, if nonce is nil
	// one is generated automatically using a CSPRNG (crypto/rand.Read)
	Sign(msg []byte, nonce []byte) (Token, error)

	// Verify authenticates the token and returns the decrypted msg
	Verify(t Token) (msg []byte, err error)
}
```

# Usage Snippet
```go
	// Configure
	key := [32]byte{ /* random data */ }
	s, _ := signer.New(key[:])

	// Sign
	tok, _ := s.Sign([]byte("hello world"), nil)
	fmt.Println(tok)
	// ul6mbjrzW_Y82_a8sQQRqlzFTPAcA65tn4xlWN3z3bpwIYZiW47JlyF34UwaUzize4yFfrN8Vzs

	// Verify
	p, err := s.Verify(tok)
	if err != nil{
		log.Fatalf("verify: %v", err)
	}
```

# Notes

## Why not use branca?
Branca's uint32 time field isn't future-proof and ignorant of time predating 1970 (time is a signed value). Time in a token specification is scope creep. Add your own time in the msg to excersize full control, since its guaranteed to be authenitc.

Branca implementations seen in the wild don't return msg if it is authentic but expired, which is useless for practical deployments. With Signer, you have the ability to log authentic but expired tokens to debug misbehaving clients or bugs in clients software.

Branca uses a binary time field, one advantage of having a time field would be visibility in your server logs. For example, if logs contained a unix timestamp as part of the branca header, you could easily see in Splunk whether a certain timestamp was expired. However, Branca uses a binary timestamp, so the benefit of having a greppable/searchable value is lost. You must decode the timestamp manually and in the correct big endian byte order before making assumptions about it even if you assume its authentic.

Branca uses base62, a poorly-defined standard (branca test vectors could not be decoded by online base62 decoders). A standard base64 encoding is easily accessible across languages and easier to implement and test.

Branca does not offer easily-available test vectors. Java implementations in the wild incorrectly implement AEADs that only authenticate the header and not the cipher text. We provide an interface that allows the user to pass in the nonce because in practice this is CRITICAL to reproducibly verifying test vectors in the implementation.

## Why not use JWT?

JWT is vulnerable to downgrade attacks, because it supports "none" as an encryption algorithm. Signer supports only one algorithm, so a downgrade attack is impossible by design. If chacha20poly1305 is broken in the distant future, you can use another type of token. It is not wise to rely on dynamic implementations based on token versions. Just tell the server what to expect.

JWT spec is complex and bloated. Signer is a bare-bones token that provides authentication and encryption only. It assumes the user can implement their own claims, authorization (not to be confused with authentication), and timeouts using the data inside the payload itself.

## Why not use Signer?

You want the client to be able to validate the contents of the token, using the servers public key. Signer does not support this usecase at the time of writing, and would require asymmetric public key encryption (which is an order of magnitude slower).

You don't want the contents of the token to be encrypted. It is typical to conflate encryption and authentication, but the two are not always necessary together. Signer both authenticates and encrypts the input.

You completely distrust the programmers. This implementation allows the user to pass in a nonce, which should be random if you want identical inputs to generate distinct outputs. Many "idiot-proof" crypto packages hide the nonce-generation away from the API. However, this makes testing a pain, and sometimes the use-case calls for a deterministic nonce.

# Base64 Encoding

The Token type uses URL-safe base64-encoding without padding characters. Below is the well-known character-set that comprises base64 url-safe encoding:

`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`

# Test Vectors

This is the output of the zero vector, composed of a 32-byte key and nonce of all zero bits in binary and base64 url-safe format for your implementation in other languages:

		name:  "zero",
		input: "",
		key:   [32]byte{},
		nonce: [24]byte{},
		binary: "A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\xac\x81ƕ\xb5;\xefw\n\xde5PU\xde",
		text:   "QQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAisgcaVtc2-73cK3jVQVd4",

repository: as/signer

gha_language: Go

repo_name: as/signer


text:
# Night Mode

## Table of contents
* [About](https://github.com/RagnarTheEverchosen/CoH2NightMode#about)
* [For Modders](https://github.com/RagnarTheEverchosen/CoH2NightMode#for-modders)
* [For Mappers](https://github.com/RagnarTheEverchosen/CoH2NightMode#for-mappers)

## About
Github repository for the Night Mode "wincondition" pack. Here are all the .scar files as well as the .xml files used to make the custom flare abilities. You can view them to get inspiration for your own implementations.

#### Supported gamemodes:
> - Annihilation
> - Annihilation 2x resources
> - Annihilation 2x resources + zoom
> - Victory Points
> - Victory Points 2x resources
> - Victory Points 2x resources + zoom

## For Modders
Wish to make your tuning mod compatible with the night mode mod?

**It is very important that you name the files as we do!**

The first thing we need to do is to create two new upgrades called `time_day` and `time_night` and set the `owner_type` to `player`.

![Upgrade](https://i.imgur.com/WrnufDd.png)

Now that we have the upgrades we can move on to the slot item. Create a slot item `time_night_slotitem` and set the `owner_type` to `squad`. And you want to set up the `on_add_action` like this:

![Slot Item](https://i.imgur.com/JzDgoh5.png)

Here you can get creative and set the `apply_modifiers_action` as you like. This will make the squads benefit from the modifiers when they have this slot item. To how the squads will acquire this slot item we will get later in this tutorial.

You also want to copy and paste this `requirement_action` and change the unit type to `hmgs`/`mortars`/`vehicle`. And again you can customize the benefits for each one of the unit types.

So far we can check if it is day or night and have a slot item that will help our units fight the night. It is time we created the auras. First, we will create an aura called `night_debuff` and set it up like this:

![Night Aura 1](https://i.imgur.com/65f7fLu.png)

Now that we have set up our first `requirement_action` lets move to the other once. They should look something like this:

![Night Aura 2](https://i.imgur.com/7o9PMvl.png)

And once again you can get creative and set the `apply_modifiers_action` as you like. These modifiers will effect the squads when the night comes. And you also want to copy and paste this `requirement_action` and change the unit type to `hmgs`/`mortars`/`vehicle`. And again you can customize the debuffs for each one of the unit types.

This was our `night_debuff` aura. Now we will create our second aura called `night_debuff_remove`. This one is simple, take a look:

![Flare Aura](https://i.imgur.com/Zq9hUAv.png)

In this next step, we will put to use everything we created so far. Let us create an EBPS file called `aura_night_debuff`.

![EBPS 1](https://i.imgur.com/tpiUvht.png)

It doesn't really matter what `animator` you use in `entity_blueprint_ext` as long you set the `is_visible_in_game` to `False`. But the most important thing here is the `radius` in your `add_aura` action. Make sure that the `radius` is set to max range possible and that is `3,402823E+38`.

Our next EBPS file will be called `aura_flare`.

![EBPS 2](https://i.imgur.com/OLRxqS4.png)

Again it doesn't really matter what `animator` you use in `entity_blueprint_ext` as long you set the `is_visible_in_game` to `False`. Here the `radius` will be equal to whatever the effect range of your flare ability that we will create in the next step is. Here in the example, it is `35`.

So as I said now we will create the flare ability for our mortars. You can copy the soviet mortar flare ability `mortar_fire_flares_ability_mp` and modify the `action_list`.

![Flare Ability](https://i.imgur.com/9KMpnm4.png)

Here we have added a new `action` to the original `action_list_sequences`. As the `entity_blueprint` we want to set our `aura_flare` that we created earlier.

The last thing you need to do is to give us your mod's GUID. You can do so by contacting [@RagnarTheEverchosen](https://steamcommunity.com/id/ragnarthegamer/) or [@JustCodiex](https://steamcommunity.com/id/CoDiEx/).

And that is it. We hope that this tutorial was easy to follow and everything works for you just fine. We also want to thank you you have chosen to make your mod compatible with Night Mode.

## For Mappers
Have you designed a map that's perfect for a night battle, and want to make better use of this mod?
Well, you're in luck!

Simply create a new .scar file in your map folder. It must be titled as:
<sgb_filename>.scar
It's very important that the scar file matches the file name of your .sgb file. (without the .sgb extension)
Nextly, open the scar file, and paste the following:
```` lua
function OnMapInit()
    Rule_AddOneShot(OnInitNightMode, 0.1);
end
Scar_AddInit(OnMapInit);
function OnInitNightMode()
    pcall(NMAPI_SetTime, "night");
end
````
The above code will make sure your map starts out like a true night. It will also make sure, no fatal scar errors happen if it's played without the night mode.


text:
[![build status](https://api.travis-ci.org/paneidos/laravel-tagged-cache.svg?branch=master)](https://travis-ci.org/paneidos/laravel-tagged-cache)
# Laravel Tagged Cache

Force a certain tag on your cache.

## Why would I need this?

If you use the same Memcache server for multiple projects/tenants, it might be difficult to flush the cache for only one of them. The only options is to flush the entire cache. Using Laravel's built in `TaggableStore`, it's possible to flush the cache for only one project/tenant.

## How does it work?

The tagged cache driver is a simple wrapper for another cache driver. All regular access to cache keys, such as `get`, `put` and `remember`, are forced to use the `tags` method and include the specified tag. Other special methods, such as `lock` are passed through without modification.

# Installation

To get started with Laravel Tagged Cache, use Composer to add the package to your project's dependencies:

```
composer require paneidos/laravel-tagged-cache
```

## Config

Specify a tagged store in your `config/cache.php`:

```php
return [
    'stores' => [
        'memcache-tagged' => [
            'driver' => 'tagged',
            'backend' => 'memcache',
            'tag' => 'project_name',
        ],
        'memcache' => [
            // ...
        ],
        // ...
    ],
];
```

## Example: replace your default store

```php
return [
    'default' => 'tagged',

    'stores' => [
        'tagged' => [
            'driver' => 'tagged',
            'backend' => env('CACHE_DRIVER', 'array'),
            // Use the database name as the forced tag
            'tag' => env('DB_DATABASE', 'none'),
        ],
        // ...
    ],
];
```

# Compatibility

Currently works with Laravel 5.6 and higher.
The backend can be any store with support for tags. Note: the file store does *not* support tags.

# Development

```
# Install dependencies
composer install
# Run tests
composer test
# Run tests & report coverage
composer test -- --coverage-text
```

# Contributing

Send a pull request, ensure you've got test coverage for the new code.

# License

Laravel Tagged Cache is licensed under the MIT License.

repository: paneidos/laravel-tagged-cache

repo_name: paneidos/laravel-tagged-cache


text:
# go-lib-template

![GitHub Workflow Status](https://img.shields.io/github/workflow/status/theflyingcodr/go-lib-template/Go?style=flat-square)
![GitHub](https://img.shields.io/github/license/theflyingcodr/go-lib-template?style=flat-square)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/theflyingcodr/go-lib-template?style=flat-square)
[![Report](https://goreportcard.com/badge/github.com/theflyingcodr/go-lib-template?style=flat&v=1)](https://goreportcard.com/report/github.com/theflyingcodr/go-lib-template)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/theflyingcodr/go-lib-template?style=flat-square)

A git template that can be used to bootstrap a go library, ie, something that isn't an executable.

This comes complete with git actions for:

* greetings  - welcome new contributors automatically
* build & release - to ensure your code is building before creating a release
* code quality - to scan for obvious issues

There is also a [Makefile](Makefile) with some handy common commands for running all tests, testing the releaser etc.

This will hopefully make a good starting point when you are looking to start a new go project.

## Getting started

* Create a new github repo
* Select this as the template
* Clone the repo
* run `go mod init github.com/youruser/yourporject`
* code code code

## Build pipeline

The go build will run on PRs and when pushed to master. When you tag master it will then run the go build and then create a release.

## Mergify

It also has a mergify config if you run that on your repos for auto merging etc.

Lets see if it works. Hmm

repository: theflyingcodr/go-lib-template

gha_language: Makefile

repo_name: theflyingcodr/go-lib-template


text:
# Database migrations

## Setting up

If you are planning to use database migrations, you need to let
Alembic know the current state of the database.

Presuming you've just started off by running `make load_demo_data`
on the latest main branch commit (this should happen on a vanilla main branch,
i.e. without any of your changes to the database schema),
tell Alembic that you are on the latest database schema:

```
PYTHONPATH=. alembic -x config=config.yaml stamp head
```

## Generate migration script

To generate a migration script, after having stamped the latest main commit (see above),
ensure that the app is stopped, check out the branch with the relevant DB schema
changes, and run the following:

```
PYTHONPATH=. alembic -x config=config.yaml revision --autogenerate -m "Revision description"
```

Review the resulting migration file under `alembic/versions` at hand of the [documentation](https://alembic.sqlalchemy.org/en/latest/autogenerate.html).

## Applying migration scripts

If the database has been stamped, as outlined above, the migration manager service
will automatically apply any pending migration scripts upon starting the app.

To manually apply migration scripts, after ensuring that the app is stopped, check
out the branch with pending migration scripts, and run the following to upgrade:

```
PYTHONPATH=. alembic -x config=config.yaml upgrade head
```

repository: skyportal/skyportal

gha_license_id: NOASSERTION

repo_name: skyportal/skyportal


text:
# Appendix: Extra Information

## Changing Versions

The normal way to change a version is to use the Admin main menu.

But...

Adding a `v` query param to a url will change the version during the call

This can be handy for switching between versions without changing the screen and renavigating.

e.g.

- http://localhost:4567/apps/pulp/gui/reports/authors/list/navigation?v=1
- http://localhost:4567/apps/pulp/gui/reports/authors/list/navigation?v=10
- or start on a specific version
    - http://localhost:4567/apps/pulp/?v=3

repository: eviltester/TestingApp

repo_name: eviltester/TestingApp


text:
---
date: 2017-02-18T11:13:45+08:00
title: "gogrpc安装"
description: ""
disqus_identifier:<PHONE_NUMBER>582977772
slug: "go-grpcan-zhuang"
source: "https://my.oschina.net/ifraincoat/blog/840386"
tags:
- golang
categories:
- 编程语言与开发
---

### Prerequisites

#### Go version

gRPC works with Go 1.5 or higher.

    $ go version

For installation instructions, follow this guide: [Getting Started - The
Go Programming Language](https://golang.org/doc/install)

#### Install gRPC

Use the following command to install gRPC.

    $ go get google.golang.org/grpc

#### Install Protocol Buffers v3

Install the protoc compiler that is used to generate gRPC service code.
The simplest way to do this is to download pre-compiled binaries for
your platform(`protoc-<version>-<platform>.zip`) from
here: [https://github.com/google/protobuf/releases](https://github.com/google/protobuf/releases)

-   Unzip this file.
-   Update the environment variable `PATH` to include the path to the
    protoc binary file.

Next, install the protoc plugin for Go

    $ go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

The compiler plugin, protoc-gen-go, will be installed in \$GOBIN,
defaulting to \$GOPATH/bin. It must be in your \$PATH for the protocol
compiler, protoc, to find it.

    $ export PATH=$PATH:$GOPATH/bin

Download the example
--------------------

The grpc code that was fetched with `go get google.golang.org/grpc` also
contains the examples. They can be found under the examples
dir: `$GOPATH/src/google.golang.org/grpc/examples`.

Build the example
-----------------

Change to the example directory

    $ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld

gRPC services are defined in a proto file, which is used to generate a
corresponding .pb.go. This file is already generated for the helloworld
example code and can be found under this
directory: `$GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld`

This `helloworld.pb.go` file contains:

-   Generated client and server code.
-   Code for populating, serializing, and retrieving
    our `HelloRequest` and `HelloReply` message types.

Try it!
-------

To compile and run the server and client code, the `go run` command can
be used. In the examples directory:

    $ go run greeter_server/main.go

From a different terminal:

    $ go run greeter_client/main.go

If things go smoothly, you will see the `Greeting: Hello world` in the
client side output.

Congratulations! You’ve just run a client-server application with gRPC.

Update a gRPC service
---------------------

Now let’s look at how to update the application with an extra method on
the server for the client to call. Our gRPC service is defined using
protocol buffers; you can find out lots more about how to define a
service in a `.proto` file in [What is
gRPC?](http://www.grpc.io/docs/) and [gRPC Basics:
Go](http://www.grpc.io/docs/tutorials/basic/go.html). For now all you
need to know is that both the server and the client “stub” have
a `SayHello` RPC method that takes a `HelloRequest` parameter from the
client and returns a `HelloReply` from the server, and that this method
is defined like this:

    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }

    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }

    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }

Let’s update this so that the `Greeter` service has two methods. Make
sure you are in the same examples dir as above
(`$GOPATH/src/google.golang.org/grpc/examples/helloworld`)

Edit `helloworld/helloworld.proto` and update it with a
new `SayHelloAgain`method, with the same request and response types:

    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {}
      // Sends another greeting
      rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
    }

    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }

    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }

Generate gRPC code
------------------

Next we need to update the gRPC code used by our application to use the
new service definition. From the same examples dir as above
(`$GOPATH/src/google.golang.org/grpc/examples/helloworld`)

    $ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

This regenerates the helloworld.pb.go with our new changes.

Update and run the application
------------------------------

We now have new generated server and client code, but we still need to
implement and call the new method in the human-written parts of our
example application.

### Update the server

Edit `greeter_server/main.go` and add the following function to it:

    func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
            return &pb.HelloReply{Message: "Hello again " + in.Name}, nil
    }

### Update the client

Edit `greeter_client/main.go` to add the following code to the main
function.

    r, err = c.SayHelloAgain(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
            log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.Message)

### Run!

gha_language: CSS


text:
# Image-dl

## What is this?

Image downloading tool.

## What for

To download images. It can be used for im clients to save images via custom plugins.

## How it works

Asynchronously downloads given picture.

```bash
curl -H 'url: http://server.tld/image.jpg' http://localhost:3088/image_dl
```

## How to run it

As [PSGI][1] application, via [UWSGI][2].

Before running this app should be bootstrapped via bootstrap.sh and [cpanm][3].

Copy config_sample to config open it and edit, put there valid dir where images will be saved.

```bash
/usr/bin/uwsgi --yaml /var/www/image-dl/image-dl.yaml \
               --psgi /var/www/image-dl/image-dl.psgi \
               --logto /var/log/image-dl.log \
               --pidfile /var/run/image-dl.pid \
               --perl-local-lib /var/www/image-dl/vendor_perl
```

[1]: https://uwsgi-docs.readthedocs.io/en/latest/Perl.html
[2]: https://github.com/unbit/uwsgi
[3]: https://github.com/miyagawa/cpanminus

repository: eleksir/image-dl

repo_name: eleksir/image-dl


text:
---
layout: post
title: "Updated TMUX, regaining splitting/creating new windows based on current directory"
date: 2014-05-28 20:16
comments: true
categories: [tmux, unix]
---
Just upgraded my copy of tmux and went to split my windows and realized that the default behaviour to split the window based on the current directory disappeared.

The quick fix to this for me (could be a better one, but I have not done any research yet) was to remap my map binding to augment the commands to maintain their old behaviour:

{% codeblock lang:bash Updating Tmux split bindings %}
bind c new-window -c '#{pane_current_path}'
bind-key d split-window -v -c '#{pane_current_path}'
bind-key % split-window -h -c '#{pane_current_path}'
{% endcodeblock %}

Each of these bindings maintain the exact same behaviour that was there prior to my tmux update.

[Develop With Passion®](http://www.developwithpassion.com)

extension: markdown