Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang migration #23

Merged
merged 36 commits into from
Sep 18, 2017
Merged

Golang migration #23

merged 36 commits into from
Sep 18, 2017

Conversation

kaustavdm
Copy link
Contributor

@kaustavdm kaustavdm commented Sep 17, 2017

In a stable enough state to merge. Moved old node branch to legacy-node branch

Note: Do not squash merge. Retain individual commits.

Note: Circle CI is disabled currently. It's not running any tests. I have overriden merge requirements for master till this PR is merged or #21 is fixed.

Fixes #17

Kaustav Das Modak added 30 commits September 5, 2017 01:45
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
@kaustavdm kaustavdm requested a review from dolftax September 17, 2017 19:28
Kaustav Das Modak added 5 commits September 18, 2017 02:47
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
Signed-off-by: Kaustav Das Modak <[email protected]>
It checks whether there is already an account for given email

Signed-off-by: Kaustav Das Modak <[email protected]>
}

// ParseConfig parses a configuration file and loads into a config
func ParseConfig(confPath string) (Config, error) {
Copy link

Choose a reason for hiding this comment

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

Unnecessary. Viper handles this for you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I always try to cut down external dependencies to a minimum, hence went ahead and wrote a basic config parsing script. Viper does the job, but we are also operating in a controlled environment, where we don't need all that abstraction. The only thing I'd want here is a merging function which can override config in JSON with environment variables (which Viper does, but it also does a lot more). In a stack where ser-de is so straightforward, I don't see much reason to add a dependency.

One argument against this view is to let go of the grunt work to external libraries and focus on the application. My counterpoint is that this approach is the highway to dependency hell and eventual tech debt.

Also, the config package is not stabilized yet. I wrote a bare minimum implementation that works, made sure it can be incrementally added and then moved on to the more important parts of the application.

Copy link

Choose a reason for hiding this comment

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

Explained you a use case couple days ago. When storing configuration in an shared system (etcd). Deploying the changes on all nodes is not the right way.

Technical debt, really? Heh. Unecessary. But upto you.

Copy link

@dolftax dolftax Sep 18, 2017

Choose a reason for hiding this comment

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

r+

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed on the deployment scenario. Though, we don't know if that will be an etcd store or something else. Also, if configuration is indeed shared and hosted separately, we may want a dedicated reader, say, if all config is published to etcd, then all what rig needs to know at launch is the link to etcd and the rest it can fetch via a etcd client. It does not need viper to do that. At that point, etcd can also be used for other purposes where viper falls short. This is what I mean by reducing abstraction and lowering tech debt eventually.

I am not saying no to viper. It definitely looks good. I'm skeptic of introducing abstractions where they were not necessary.

(Check differences between "necessary" and "sufficient" clauses)

}

// CreateConfig generates a default JSON config file and writes to the given path
func CreateConfig(confPath string) (Config, error) {
Copy link

Choose a reason for hiding this comment

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

''

Copy link
Contributor Author

Choose a reason for hiding this comment

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

?

Copy link

Choose a reason for hiding this comment

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

Similar to above issue.

Copy link

@dolftax dolftax Sep 18, 2017

Choose a reason for hiding this comment

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

r+

serverConfig{
Port: 8081,
JWTSecret: "replacemewithanicelongstringthatyouwillnotsharewithothers",
PostgresURL: "postgres://user:pass@host/db",
Copy link

Choose a reason for hiding this comment

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

Why hardcode this? This has to be decoupled from code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is decoupled. The values there are dummy values meant to be changed. The whole purpose of this function is generate a dummy JSON config and then go ahead and edit the values. This approach is testable, does not need to maintain a sample file, gets compiled with the binary and hence can be kept updated per deployment.

Decoupling is not always about building a separate module. It is functional. A config module is decoupled. It can read config and can suggest initial config.

Copy link

Choose a reason for hiding this comment

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

Ideally, configuration should be maintained outside the code in general parsable formats (JSON, YAML, ..)

Copy link

@dolftax dolftax Sep 18, 2017

Choose a reason for hiding this comment

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

r+

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Configuration should be maintained externally. Configuration structure should be internal. This generates dummy values, but with the right structure. Think npm init -y.

- package: golang.org/x/crypto
- package: github.com/go-pg/pg
version: ^6.4.24
- package: github.com/jinzhu/inflection
Copy link

Choose a reason for hiding this comment

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

:|

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what?

Copy link

Choose a reason for hiding this comment

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

Highway to dependency hell.

Copy link

@dolftax dolftax Sep 18, 2017

Choose a reason for hiding this comment

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

r+

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which one on the list? Keep in mind that I talk of reducing dependency wherever possible, while not necessarily making it zero. Each item on this list has been thoroughly researched, compared, tested and then added to the list. jinzhu/inflection is explicitly on the list because glide kept failing to detect that it is a dependency of go-pg/pg. If I find it otherwise, I'm more than happy to remove it.

Difference between necessary and sufficient.

package models

// EdgeCluster stores DNS and location information for edge clusters
type EdgeCluster struct {
Copy link

Choose a reason for hiding this comment

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

Edge cluster? I would avoid using the name cluster as it contradicts with the indenepdent application.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are edge clusters. Not to be confused with independence. I see a pattern come up in your comments so let me address this clearly.

"Independence" is the lack of being dictated every action. "Decoupling" is the ability to have atomic responsibilities. "Distributed" is the ability to coordinate and execute responsibilities beyond physical boundaries. "Isolated" means lack of connectivity. "Ignorance" is the lack of knowledge. Independent does not imply decoupled. Distributed does not imply independent. Distributed may need to be decoupled. But, neither of these require ignorance.

In this case, rig needs to have knowledge of what edge clusters are deployed. Agents are deployed in nodes in edge clusters. 1 edge cluster can have one or more agent nodes. Customers of xplex interact with edge clusters and not with agent nodes. So, rig needs this information to correctly tell customers where to stream. This information can be manually added in the initial stages and can later be automated.

So, in this case, rig operates independent and distributed. Agents are distributed, but dependent on rig; they perform actions on the edge nodes behalf of rig. Agents operate under the assumption that there are many other agents, but they are isolated from each other. Rig sees the whole picture and coordinates as needed. Agents have basic instructions to figure out how to perform certain actions locally and only pass on the result of those actions to the rest of the system.

Copy link

Choose a reason for hiding this comment

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

r+

return false
}
return true
}
Copy link

Choose a reason for hiding this comment

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

Neat 👍

)

// Private key type to prevent context key collisions
type key int
Copy link

Choose a reason for hiding this comment

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

Better name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thought of it, but then decided to keep it as simple name in private scope. This was also suggested in some go blogs. I like the simplicity. Though, one possibility is to rename it to ctxKey. Does that make sense?

Copy link

Choose a reason for hiding this comment

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

r?

Email: r.FormValue("email"),
}
if err := u.SetPassword(r.FormValue("password")); err != nil {
log.Printf("Error setting user password. Reason: %s\n", err)
Copy link

Choose a reason for hiding this comment

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

Use println. Needn't do \n.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

println doesn't allow a format specifier. I usually use some format in logs. \n is a common method of adding line break as required.

Copy link

Choose a reason for hiding this comment

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

Seperate by commas? log.Println("Error doing this", err)

jwt.StandardClaims{
Issuer: fmt.Sprintf("%d", u.ID),
Subject: u.Username,
Audience: "rig.xplex.me",
Copy link

Choose a reason for hiding this comment

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

Pick from env (or) config

Copy link

Choose a reason for hiding this comment

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

r?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, nope, nope. This is functional style dependency injection. Testable and atomic. Whoever supplies the secret can choose to do so from env or config.

jwt.StandardClaims{
Issuer: senderid,
Subject: email,
Audience: "rig.xplex.me",
Copy link

Choose a reason for hiding this comment

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

''

Copy link

Choose a reason for hiding this comment

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

Pick from configuration. r?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do you speak unspoken sentences?

Copy link
Contributor Author

@kaustavdm kaustavdm Sep 18, 2017

Choose a reason for hiding this comment

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

Nope. See comment above.

Signed-off-by: Kaustav Das Modak <[email protected]>
@dolftax dolftax merged commit b4fce63 into master Sep 18, 2017
@dolftax dolftax deleted the golang branch September 18, 2017 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move stack to Golang
2 participants