This is a creation in Article, where the information may have evolved or changed.
Original: Inside the Go Playground
Brief introduction In September 2010, we introduced Go Playground, a Web server that consists entirely of Go code and returns the results of a program run. If you're a go programmer, you've probably already used go playground by reading the Go tutorial or the sample program in the Go document. You can also use it by clicking the "Run" button on the talks.golang.org slide or a program on a blog (such as a recent blog about strings). In this article we will learn how go playground is implemented and integrated with other services. The implementation involves different operating systems and running times, and here we assume that all the systems used to write go are basically the same. |
Cmy00cmy Translated 10 months ago 1 Person top top translation of good Oh! |
overview The Playground service has three parts:
- A backend that runs on top of Google services. It receives the RPC request, compiles the user program with the GC tool, executes, and returns the output (or compilation error) of the program as an RPC response.
- A front end that runs on Gae. It receives an HTTP request from the client and generates the appropriate RPC request to the backend. It also does some caching.
- A JavaScript client implements the user interface and generates an HTTP request to the front-end.
|
Garfielt translated 10 months ago 1 Human top top Good translation! |
backend The Backend program itself is very simple, so here we don't discuss its implementation. The interesting part is how we securely execute arbitrary user code in a secure environment, while also providing core functionality such as time, network, and file systems. Isolates user programs from Google's infrastructure, and the backend runs them in the native Client (or "NaCl"), the Native Client (NaCl)-a technology developed by Google that allows the x86 program to execute securely in a Web browser. The backend uses a special version of the GC tool that can generate a NaCl executable file. (This special tool will be merged into Go 1.3.) To learn more, read the design documentation. If you want to experience NaCl in advance, you can check out a branch that contains all the changes. |
Garfielt translated 10 months ago 1 Human top top Good translation! |
| Local clients limit the amount of CPU and RAM used by the program , it also prevents programs from accessing the network and the file system. However, this can lead to a problem with many of the key advantages of the Go program, such as concurrency and network access. In addition, access to the file system is critical for many programs. We need time capabilities to demonstrate high-performance concurrency. Obviously we need networks and file systems to show the benefits of accessing network and file systems. Although these features are now supported, none of the first versions of playground released in 2010 were supported. The current time function is supported in November 2009 of 10, but time. Sleep is not available, and most systems and network-related packages are not supported A year later, we implemented a pseudo-time on the playground, which allowed the program to have a proper sleep behavior. Newer playground updates introduce pseudo-network and pseudo-file systems, which make the playground tool chain the same as the normal Go tool chain. These newly introduced features are described in detail below. |
Mitisky translated 10 months ago 1 Human Top top Good translation! |
pseudo-time The programs available in the Playground are limited in CPU time and memory. In addition, the actual time of application is also limited. This is because each program running in Playground consumes background resources and occupies the infrastructure between the client and the backend. Limiting the uptime of each program makes our maintenance more accessible and protects us from denial-of-service attacks. But these limits become very inappropriate when the program uses the time function function. In the Go Concurrency patterns speech, an example is presented to illustrate this terrible problem. This is a time function function such as times. Sleep time. After the example program, when running in the earlier playground , these programs hibernate and behave strangely (sometimes even error) |
Mitisky translated 10 months ago 1 people top top The translation is good Oh! |
By using a clever trick, we can make the GO program think it is in hibernation, while actually this hibernation does not take any time. Before we introduce this trick, we need to understand that the scheduler is the principle of managing goroutine sleep. When a goroutine calls time. Sleep (or other similar functions), the scheduler adds a timer to the suspended timer heap and lets Goroutine hibernate. During this time, a special Goroutine calculator manages the heap. When this special Goroutine calculator starts to work, it first tells the scheduler that it wakes itself up when the next suspended timer in the heap is ready to be timed, and then it begins to hibernate itself. When this special timer is awakened, the first is to detect if there is a timer timeout, if so, wake up the corresponding goroutine, and then go back to hibernation. Having understood this principle, the trick is simply to change the condition of the timer that wakes the goroutine. The scheduler does not wake up after a period of time, and only waits for a deadlock that all goroutines are blocked to occur. |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
| Other translation versions (1) |
Loading ...
| Playground Run-time version maintains an internal Clock. When the modified scheduler detects a deadlock, it checks to see if there are some pending timers. If so, it adjusts the time of the internal clock to the time of the earliest timer, and then wakes up the goroutine timer. This keeps repeating, and the program thinks that time is over, and actually hibernation is almost no time consuming. These scheduler changes are detailed in proc.c and  TIME.GOC. The Pseudo-time solves the problem of background resource exhaustion, but what about the output of the program? How strange it is to see a dormant program that does almost no time to get the job done correctly! |
Mitisky translated 10 months ago 0 Human Top top Good translation! |
The following program outputs the current time per second and then exits after three seconds. Try to run it. Func Main () { stop: = time. After (3 * time. Second) tick: = time. Newticker (1 * time. Second) defer tick. Stop () for { Select {case <-tick. C: FMT. Println (time. Now ()) Case <-stop: return }} }How is this done? This is actually the result of working with the backend, front end, and client. We capture the time of the output to standard output and standard error, and make this time available to the client. Then the client can output at the correct time interval, so that the output is the same as the local program output. |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
Playground's Run environment package provides a special write function that introduces a small "replay header" before each write to the data. The playback header contains a logical character, the current time, to write the data length. The playback header for a write operation is structured as follows: The original output of this program is similar to this: \x00\x00pb\x11\x74\xef\xed\xe6\xb3\x2a\x00\x00\x00\x00\x1e2009-11-10 23:00:01 +0000 UTC\x00\x00PB\x11\x74\xef\xee \x22\x4d\xf4\x00\x00\x00\x00\x1e2009-11-10 23:00:02 +0000 utc\x00\x00pb\x11\x74\xef\xee\x5d\xe8\xbe\x00\x00\x00\ x00\x1e2009-11-10 23:00:03 +0000 UTC The front end parses these outputs into a series of events and returns a JSON object to the client's list of events: { "Errors": "", "Events": [ { "Delay": 1000000000, "Message": "2009-11-10 23:00:01 +0000 utc\n" }, { "delay": 1000000000, "Message": "2009-11-10 23:00:02 +0000 utc\n" }, { "delay": 1000000000, "Message": "2009-11-10 23:00:03 +0000 utc\n" } ]} The JavaScript client (which runs in the user's Web browser) then replays the event using the provided delay interval. It appears to the user that the program is running in real time. |
Garfielt Translated 10 months ago 1 Person top top translation of good Oh! |
Pseudo file System Programs built on the Go Local client (NaCl) Toolchain are not able to access the local machine's file system. In order to solve this problem, a file access function (Open, Read, Write, and so on) in the Syscall package is operated on a memory file system. This memory file system is implemented by the Syscall package itself. Since the Syscall package is an interface between the go code and the operating system memory, the user program treats the pseudo-file system as if it were a real file system. The following example program writes data to a file so that the content is copied to standard output. Try to run it (you can edit it too) Func Main () { const filename = "/tmp/file.txt" err: = Ioutil. WriteFile (filename, []byte ("Hello, File system\n"), 0644) if err! = Nil { log. Fatal (Err) } B, err: = Ioutil. ReadFile (filename) if err! = Nil { log. Fatal (Err) } fmt. Printf ("%s", b)} When a process starts, this pseudo file system joins the device in the/dev directory and A/tmp empty directory. Then the program can operate on the same file system as usual, but after the process exits, all changes to the file system will be lost. |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
| When initializing, you can upload a zip archive (see Unzip_ NACL.GO) So far only in the standard library testing, we will use the decompression tool to provide test data files. But we're going to playground the program to run data from sample documents, blog posts, and Golang tutorials. The Implementation is detailed in the fs_nacl.go and fd_nacl.go files (due to the _nacl suffix, these files are added to syscall in the package). This pseudo file system is represented by Fsys struct. One of the global instances (called FS) is created at initialization time. Various file-related functions operate on FS instead of making real system calls. For example, here is a syscall. Open function: func Open (path string, OpenMode int, perm uint32) (fd int, err error) {Fs.mu.Lock () defer fs.mu.Unlock () F, err : = Fs.open (Path, OpenMode, perm&0777| S_IFREG) If err! = Nil {return-1, err} return NEWFD (f), nil} |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
The file descriptor is recorded by a global fragment called files. Each filename descriptor corresponds to a file, and each of the files provides an implementation of the Fileimpl interface. Here are the implementations of several interfaces:
- Fsysfile represents regular files and equipment (such as/dev/random),
- Standard input and output and standard errors are instances of naclfile, which can use system calls to manipulate real files (this is the only way for programs in the playground to access the external environment,
- Network sockets have their own implementations, which are discussed in the following sections.
Pseudo Network access Like the file system, the playground network stack is simulated by the Syscall package inside the process, which allows the playground project to use the loopback address (127.0.0.1). However, you cannot request additional hosts. |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
| Run the following executable instance code. This program first listens to the TCP port, then waits for the connection to arrive, then copies the connection data to the standard output, and finally the program exits. In another Goroutine, he connects to the listening port, writes the data to the connection, and finally shuts down. func main () {L, err: = Net. Listen ("TCP", "127.0.0.1:4000") if err! = Nil {log. Fatal (ERR)} defer l.close () go dial () c, err: = L.accept () if err! = Nil {log. Fatal (ERR)} defer c.close () io. Copy (OS. Stdout, c)}func dial () {c, err: = Net. Dial ("TCP", "127.0.0.1:4000") if err! = Nil {log. Fatal (ERR)} defer C.close () c.write ([]byte ("Hello, network\n")} The interface of the network is much more complex than the file, so the implementation of the pseudo-network interface is larger than the pseudo-file system and More complicated than that. Pseudo-networks must simulate read and write timeouts, as well as handling different address types and protocols, and so on. For details, see Net_nacl.go. It is recommended to start reading from Netfile because this is the implementation of the network socket for the Fileimpl interface. |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
Front The front end of the playground is another simple program (less than 100 lines). Its primary function is to accept HTTP requests from the client and then issue the corresponding RPC requests to the background, while some cache work is done. The front end provides an HTTP handler, see Http://golang.org/compile. This handler accepts a POST request with the body tag that contains the Go program code to run and an optional version tag (most clients should be ' 2 '). When the current side receives an HTTP compile request, it first looks at the cache and checks to see if the same compilation request has been done before. If the presence of the same is found, the cached response is returned directly. Caching can prevent the background from being overloaded by popular programs like the Go home page. If the request has not been cached before, the front end sends the appropriate RPC request to the background, then caches the response from the background, analyzes the corresponding event replay (see Pseudo time), and finally returns the JSON-formatted object to the client via an HTTP response (as described above). |
Mitisky Translated 10 months ago 1 Person top top translation of good Oh! |
client Various sites using playground, Share some of the same JavaScript code to build the user Interface (Code window and Output window, run button, etc.), through which the playground front end interaction. The is implemented in the Go.tool Library's playground.js file and can be imported through the Go.tools/godoc/static package. Some of the code is more concise and somewhat cumbersome, as this is a combination of several different client code. The Playground function uses some HTML elements and then forms an interactive playground widget. You can use these functions if you want to add playground to your site. Transport interface (informal definition, JavaScript script) is designed to be based on web site front-end interaction. HTTPTransport is an transport implementation that can send HTTP-based protocols as described earlier. SocketTransport is another implementation that sends WebSocket (see ' Playing Offline ' below). To comply with the same-origin policy, various web site servers (such as Godoc) complete proxy requests by playground the service under http://golang.org/compile. This agent is done through a common go.tools/playground package. |
Mitisky translated 10 months ago 1 Human Top top Good translation! |
away The line runs Either the Go tour or the present tool can be run offline. Such offline functionality is great for people who have limited access to the network. To run offline, these tools run a special version of the Playground backend locally. This particular backend uses the regular go Tool, which does not have the modifications mentioned above, and uses Websocker to communicate with the client. The backend implementations of the WebSocket are described in the Go.tools/playground/socket package. The code details were discussed in the inside present speech. |
Mitisky translated 10 months ago 1 Human Top top Good translation! |
other clients Playground service is not just for the official use of the Go Project (go by example is another example). We are happy that you can use the service at your site. Our only requirement is that you contact us in advance to use a unique user agent in your request (so that we can confirm your identity) and that the services you provide are beneficial to the go community. concluding Whether it's Godoc, tour, or blog,playground has become an integral part of the Go Documentation series. With the recent introduction of pseudo-file systems and pseudo-network stacks, we will be thrilled to refine our learning materials to cover these new content. But, finally, playground is just the tip of the iceberg, and as the local client ( Native client ) is going to support Go1.3, we look forward to the community making better features. This article is an article in go Advent calendar for December 12th , and go Advent calendar is a collection of blog posts. Author Andrew gerrand related articles
- learn Go from your Browser
- Introducing the Go Playground
|
Mit Isky Translated 10 months ago 1 people top top good translation! /td> |
All translations in this article are for learning and communication purposes only, please be sure to indicate the translator, source, and link to this article.
Our translation work in accordance with the CC agreement, if our work has violated your rights and interests, please contact us promptly