Click on "Cloud Recommended Big Coffee" with one click, to get the official recommended boutique content, and not to get lost in learning technology!
5G remote control scenario has very high requirements for real-time audio and video transmission delay, stall rate, and weak network resistance. This article will introduce how to combine the characteristics of 5G networks to perform in real-time audio and video communication links. Joint optimization to meet the remote control needs of industry scenarios and reduce picture delay.
In the first part, we introduced the three concepts of module path, version number and compatibility principle, and pseudo version number. In the next part, we will continue to introduce the core concepts of Go Modules.
Four: the main version number suffix
Starting from the major version number 2, a suffix like /v2 that matches the major version number must be added to the module path. For example, if the path of a module in version v1.0.0 is example.com/test, then its path in v2.0.0 will be example.com/test/v2.
The suffix of the major version number follows the import compatibility rules:
If a new code package has the same import path as an old code package, then the new package must ensure backward compatibility with the old code package.
By definition, the packages in the new major version of the module are not backward compatible with the corresponding packages in the previous major version. Therefore, starting from v2, the package needs a new import path. This is achieved by adding a major version suffix to the module path. Since the module path is the prefix of the import path of each package in the module, adding the major version suffix to the module path can provide a different import path for each incompatible version.
Major version v0 or v1 does not allow the use of major version suffixes. The module path between v0 and v1 does not need to be changed, because the v0 version is unstable and there is no compatibility guarantee. In addition, for most modules, v1 is backward compatible with the latest v0 version, and the v1 version has only begun as a commitment to compatibility.
There is a special case, the module path starting with gopkg.in/ must always have the major version suffix, even for the v0 and v1 versions. The suffix must start with a dot instead of a slash (for example, gopkg.in/yaml.v2). Because before the launch of Go Modules, gopkg.in followed this rule. In order to make the code imported into the gopkg.in package continue to be imported and compiled, Go has done some compatibility work.
The major version suffix allows multiple major versions of a module to coexist in the same build. This can solve the diamond dependency conflict (diamond dependency conflict) https://jlbp.dev/what-is-a-diamond-dependency-conflict. Generally, if a transitive dependency requires a module in two different versions, the higher version will be used. However, if the two versions are incompatible, neither version will satisfy all callers. Since incompatible versions must have different major version numbers, the major version suffixes have different module paths, so there is no conflict: modules with different suffixes are treated as separate modules, and their package import paths are also different.
Because many Go projects released v2 or later versions before migrating to Go modules, the major version suffix was not used. For these versions, Go is annotated with the +incompatible build flag (for example, v2.0.0+incompatible).
Five: The process of parsing package path to module path
Usually when using "go get" you may specify a package path instead of a module path. How does Go find the module path?
The go command will search the build list of the main module (current module) for which module paths match the prefix of this package path. For example, if the imported package path is example.com/a/b and it is found that example.com/a is a module path, then it will check whether example.com/a contains this package in the b directory. In this At least one go source file must exist in the directory to be considered a valid package. Build Constraints will not be applied during this process. If a module containing this package is indeed found in the build list, then this module will be used. If no module is found to provide this package or two or more modules are found to provide this package, then the go command will prompt an error. But you can specify -mod=mod to make the go command try to download packages that cannot be found locally, and update go.mod and go.sum. The two commands go get and go mod tidy will automatically do these tasks.
When the go command tries to download a new code package, it goes back and checks the GOPROXY environment variable, which is a comma-separated list of URLs. Of course, keywords like direct and off are also supported. The proxy URL means that go will use the GOPROXY protocol to pull the module, direct means that go needs to interact directly with the version control system, and off does not require any interaction with the outside world. In addition, GOPRIVATE and GONOPROXY environment variables can also finely control the Go downloading code package strategy.
For each item in the GOPROXY list, the go command goes back to request each prefix of the module path. For the successfully requested module, the go command goes back to download the latest module and checks whether this certain block contains the requested package. If multiple modules contain the requested package, the one with the longest path will be selected. If the package is not included in the module found, an error will be reported. If no module is found, the go command will try the next configuration item in the GOPROXY list. If it is not found, an error will be reported. For example, suppose the user wants to get the golang.org/x/net/html package, and the previously configured GOPROXY is https://corp.example.com, https://goproxy.io. The go command will follow the following request sequence:
Initiate a request to https://corp.example.com/ (parallel):
Request for latest version of golang.org/x/net/html
Request for latest version of golang.org/x/net
Request for latest version of golang.org/x
Request for latest version of golang.org
If https://corp.example.com/ fails and returns a 410 or 404 status code, initiate a request https://proxy.golang.org/
Request for latest version of golang.org/x/net/html
Request for latest version of golang.org/x/net
Request for latest version of golang.org/x
Request for latest version of golang.org
When a required module is found, the go command will add the path and corresponding version of the dependent module to the go.mod file of the main module. This ensures that the same module version will be used when compiling the module in the future, ensuring the repeatability of the compilation. If the parsed code package is not directly referenced by the main module, there will be a // indirect comment after the new dependency added in the go.mod file.
Six: go.mod file
As mentioned earlier, the definition of a module is defined by a UTF-8 encoded text file named go.mod. This file is organized "line-oriented". Each line has an independent instruction, composed of a reserved keyword and some parameters. for example:
module example.com/my/thing
go 1.17
require example.com/other/thing v1.0.2
require example.com/new/thing/v2 v2.3.4
exclude example.com/old/thing v1.2.3
replace example.com/bad/thing v1.4.5 => example.com/good/thing v1.4.5
retract [v1.9.0, v1.9.5]
The keywords at the beginning can be grouped into blocks in the form of lines, just like the daily imports, so they can be changed to the following:
require (
example.com/new/thing/v2 v2.3.4
example.com/old/thing v1.2.3
)
The design of the go.mod file takes into account the readability of the developer and the ease of writing of the machine. The go command also provides several sub-commands to help developers modify the go.mod file. For example, the go get command can update the go.mod file when needed. The go mod edit command can do some low-level modification operations on files. If we have similar needs, we can use the golang.org/x/mod/modfile package to make the same changes programmatically. Through this package, you can also get a glimpse of the struct structure of the underlying go.mod:
// The composition of the go.mod file
type File struct {
Module *Module // Module path
Go *Go // Go version
Require []*Require // dependent module
Exclude []*Exclude // Exclude module
Replace []*Replace // Replace module
Retract []*Retract // Withdraw the module
}
// A Module is the module statement.
type Module struct {
Mod module.Version
Deprecated string
}
// A Go is the go statement.
type Go struct {
Version string // "1.23"
}
// An Exclude is a single exclude statement.
type Exclude struct {
Mod module.Version
}
// A Replace is a single replace statement.
type Replace struct {
Old module.Version
New module.Version
}
// A Retract is a single retract statement.
type Retract struct {
VersionInterval
Rationale string
}
You can see the structure of "Deprecated" from the struct of Module above. There was no such design in the early days of Go Modules. So what is this field for? It is estimated that many people do not know that if the main version of a module we maintain evolves from v1 to v2, and no longer maintains the v1 version, we hope that users use v2 as much as possible. Through the above introduction, we know that v1 and v2 are different import paths. "Retract" is also helpless. At this time, this "Deprecated" will work. Look at the following example:
// Deprecated: in example.com/a/b@v1.9.0, the latest supported version is example.com/a/b/v2.
module example.com/a/b
go 1.17
When the user gets the version of example.com/a/b again, the go command can perceive that this version is no longer maintained, and it will report to the user:
go get -d example.com/a/b@v1.9.0
go: warning: module example.com/deprecated/a is deprecated: in example.com/a/b@v1.9.0, the latest supported version is example.com/a/b/v2
The user can then pull the v2 code according to the prompts.
The article "Go modules basic and refined, full analysis of the six core concepts" comprehensively introduces the modules, module paths, packages, and package paths in Go Modules, how to find module paths through package paths, and also introduces version numbers and pseudo-version numbers. Finally, A brief introduction to the go.mod file and the unknown "Deprecated" function in it. Understanding these concepts, design concepts and compatibility principles will be of great help to the management and maintenance of your Go modules.
The above concepts are the content that we will frequently encounter when using the Go language. Understanding the difference between version numbers and pseudo-version numbers and design principles can help us understand how important it is to define our own tags in accordance with semver's standards. At the same time, following the compatibility principle defined by Go Modules, upstream and downstream developers will become more friendly and efficient when they collaborate in the community. The next series of articles will begin to learn more about the design details in Go Modules, such as detailed explanations of the go.mod file and supporting go mod subcommands, so stay tuned. In addition, Tencent cloud goproxy Enterprise has been commercialized, need to understand the students can click here .
Recommended articles by : 161bc6dba25993 Go modules are based on advanced, full analysis of the six core concepts (
Go modules are basic and refined, and the six core concepts are fully analyzed (Part 2)
"Yun Recommended Big Coffee" is a special column of Tencent Cloud Plus community content. Cloud recommendation officials specially invite industry leaders to focus on the implementation of cutting-edge technologies and theoretical practice, and continue to interpret hot technologies in the cloud era and explore new opportunities for industry development. click one-click to subscribe to , we will regularly push premium content for you.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。