### Install NetFunnel-Go Source: https://github.com/antegral/netfunnel-go/blob/main/README.md Use this command to install the NetFunnel-Go library using go get. ```sh $ go get github.com/antegral/netfunnel-go ``` -------------------------------- ### Example Usage of NetFunnel-Go Client Source: https://github.com/antegral/netfunnel-go/blob/main/README.md This example demonstrates how to initialize the NetFunnel client, obtain a ticket, and integrate it with an http.Client's cookie jar for authenticated requests to an application API. ```go import ( "net/http" "net/http/cookiejar" "net/url" "github.com/antegral/netfunnel-go" ) const NETFUNNEL_API = "https://netfunnel.example.com/ts.wseq" const APPLICATION_API = "https://api.example.com" func main() { // 1. Create a Client struct for NetFunnel. nf := Netfunnel.Client{ ApiEndpoint: NETFUNNEL_API, RetryInterval: 1 * time.Second, } // 2. Get a valid ticket for NetFunnel. // If the queue is full, it will wait for a ticket to become valid. ticket := nf.GetTicket() // 3. Put the ticket into the cookie jar. jar, _ := cookiejar.New(nil) var cookies []*http.Cookie cookie := &http.Cookie{ Name: "NetFunnel_ID", Value: ticket.Id, } cookies = append(cookies, cookie) jar.SetCookies(&url.URL{Host: APPLICATION_API}, cookies) // 4. Now use it as you would normally use a cookie jar. client := http.Client{ Jar: jar, } // 5. Done! client.Post(APPLICATION_API, "application/json", nil) } ``` -------------------------------- ### Full End-to-End NetFunnel Integration Source: https://context7.com/antegral/netfunnel-go/llms.txt This example shows how to acquire a NetFunnel ticket, use it to authenticate with a downstream API by injecting it as a cookie, and then release the ticket. Ensure the NetFunnel client and API endpoints are correctly configured. ```go // Ticket struct definition (for reference): // type Ticket struct { // Id string // full result string; used as NetFunnel_ID cookie value // Ip string // NetFunnel server IP/host // Key string // ticket key used for waitlist checks // Nnext int // number of tickets ahead in queue // Nwait int // number of clients currently waiting // Port int // server port // Tps int // transactions per second allowed // Ttl int // time-to-live for this ticket (seconds) // } // Full end-to-end integration example: get ticket, attach as cookie, call API, dispatch import ( "log" "net/http" "net/http/cookiejar" "net/url" "time" netfunnel "github.com/antegral/netfunnel-go" ) const NETFUNNEL_API = "https://netfunnel.example.com/ts.wseq" const APPLICATION_API = "https://api.example.com" func main() { nf := netfunnel.Client{ ApiEndpoint: NETFUNNEL_API, RetryInterval: 1 * time.Second, } // Acquire ticket (blocks until queue clears) ticket, err := nf.GetTicket() if err != nil { log.Fatalf("GetTicket error: %v", err) } defer func() { if err := nf.DispatchTicket(&ticket); err != nil { log.Printf("DispatchTicket error: %v", err) } }() // Inject ticket ID into HTTP cookie jar jar, _ := cookiejar.New(nil) appURL, _ := url.Parse(APPLICATION_API) jar.SetCookies(appURL, []*http.Cookie{ {Name: "NetFunnel_ID", Value: ticket.Id}, }) // Use a standard http.Client with the cookie jar client := http.Client{Jar: jar} resp, err := client.Post(APPLICATION_API+"/resource", "application/json", nil) if err != nil { log.Fatalf("API call error: %v", err) } defer resp.Body.Close() log.Printf("API response status: %s", resp.Status) } ``` -------------------------------- ### Get Access Ticket with Retries Source: https://context7.com/antegral/netfunnel-go/llms.txt Request an access ticket. Blocks and retries if the queue is full (HTTP 201) until a ticket is obtained (HTTP 200). Handles errors for other status codes. ```go import ( "fmt" "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } fmt.Printf("Ticket ID : %s\n", ticket.Id) fmt.Printf("Server IP : %s\n", ticket.Ip) fmt.Printf("Port : %d\n", ticket.Port) fmt.Printf("TTL : %d\n", ticket.Ttl) fmt.Printf("Wait count: %d\n", ticket.Nwait) // Output (example): // Ticket ID : 1:1:ip=nf.example.com&key=abc123&nnext=0&nwait=0&port=80&tps=100&ttl=300 // Server IP : nf.example.com // Port : 80 // TTL : 300 // Wait count: 0 ``` -------------------------------- ### Configure NetFunnel Client Source: https://context7.com/antegral/netfunnel-go/llms.txt Initialize the Client struct with the NetFunnel API endpoint and a retry interval for polling. ```go import ( "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", // service-specific endpoint RetryInterval: 1 * time.Second, // polling interval when queue is full } ``` -------------------------------- ### Client.GetTicket() Source: https://context7.com/antegral/netfunnel-go/llms.txt Requests an access ticket from the NetFunnel server. It automatically retries if the queue is full until a ticket is obtained. The returned ticket contains all necessary information for downstream API calls. ```APIDOC ## Client.GetTicket() ### Description Requests an access ticket from the NetFunnel server. If the server responds with HTTP 200, the queue is clear and a ticket is returned immediately. If the server responds with HTTP 201, the queue is full and `GetTicket` blocks, repeatedly calling `CheckWaitlist` at the configured `RetryInterval` until the ticket becomes valid (HTTP 200). Any other status code results in an error. ### Method `GetTicket()` ### Parameters None ### Request Example ```go import ( "fmt" "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } fmt.Printf("Ticket ID : %s\n", ticket.Id) fmt.Printf("Server IP : %s\n", ticket.Ip) fmt.Printf("Port : %d\n", ticket.Port) fmt.Printf("TTL : %d\n", ticket.Ttl) fmt.Printf("Wait count: %d\n", ticket.Nwait) ``` ### Response #### Success Response (200 OK) - **ticket** (*Ticket*): An object containing the access ticket details. - **Id** (string): The unique identifier for the ticket. - **Ip** (string): The IP address of the NetFunnel server. - **Port** (int): The port number to connect to. - **Ttl** (int): Time-to-live for the ticket in seconds. - **Nwait** (int): The number of clients currently waiting. - **Key** (string): The key associated with the ticket, used for subsequent checks. #### Response Example ```json { "Id": "1:1:ip=nf.example.com&key=abc123&nnext=0&nwait=0&port=80&tps=100&ttl=300", "Ip": "nf.example.com", "Port": 80, "Ttl": 300, "Nwait": 0, "Key": "abc123" } ``` ``` -------------------------------- ### Client.DispatchTicket() Source: https://context7.com/antegral/netfunnel-go/llms.txt Notifies the NetFunnel server that a session is complete, releasing the access ticket and freeing up a slot in the queue. This should be called to ensure efficient queue management. ```APIDOC ## Client.DispatchTicket() ### Description Notifies the NetFunnel server that the session is complete and releases the ticket, freeing a slot in the queue for the next waiting client. It should be called with `defer` or explicitly after all downstream API calls are finished. Failing to dispatch results in the ticket occupying a queue slot until its TTL expires. ### Method `DispatchTicket(ticket *Ticket)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go import ( "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } defer func() { if err := nf.DispatchTicket(&ticket); err != nil { log.Printf("warning: failed to dispatch ticket: %v", err) } }() // ... perform downstream API calls using the ticket ... ``` ### Response #### Success Response (200 OK) Indicates the ticket was successfully dispatched. ``` -------------------------------- ### Client.CheckWaitlist() Source: https://context7.com/antegral/netfunnel-go/llms.txt Polls the NetFunnel server to check the status of a waitlist ticket. It returns the HTTP status code from the server, indicating whether the ticket is valid (200) or if the client is still in the queue. ```APIDOC ## Client.CheckWaitlist() ### Description Sends a status check request to the NetFunnel server using a previously obtained ticket key. It returns the HTTP status code from the server: `200` means the ticket is now valid and the client may proceed; any other code indicates the client is still in the queue. This method is called automatically inside `GetTicket` during queue waiting but can also be used independently. ### Method `CheckWaitlist(ticketKey string)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```go import ( "fmt" "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } // Manually check if the ticket key is still valid statusCode, err := nf.CheckWaitlist(ticket.Key) if err != nil { log.Fatalf("waitlist check failed: %v", err) } if statusCode == 200 { fmt.Println("Ticket is valid, proceed with API call") } else { fmt.Printf("Still in queue, HTTP status: %d\n", statusCode) } ``` ### Response #### Success Response (200) - **statusCode** (int): The HTTP status code from the NetFunnel server. `200` indicates the ticket is valid. ``` -------------------------------- ### Dispatch Access Ticket Source: https://context7.com/antegral/netfunnel-go/llms.txt Notify the NetFunnel server that a session is complete and release the ticket. Use with `defer` to ensure release after API calls. ```go import ( "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } defer func() { if err := nf.DispatchTicket(&ticket); err != nil { log.Printf("warning: failed to dispatch ticket: %v", err) } }() // ... perform downstream API calls using the ticket ... ``` -------------------------------- ### Check Waitlist Status Independently Source: https://context7.com/antegral/netfunnel-go/llms.txt Poll the waitlist status using a ticket key. Returns HTTP 200 if the ticket is valid, or another status code if still in the queue. Useful for manual status checks. ```go import ( "fmt" "log" "time" netfunnel "github.com/antegral/netfunnel-go" ) nf := netfunnel.Client{ ApiEndpoint: "https://netfunnel.example.com/ts.wseq", RetryInterval: 1 * time.Second, } ticket, err := nf.GetTicket() if err != nil { log.Fatalf("failed to get ticket: %v", err) } // Manually check if the ticket key is still valid statusCode, err := nf.CheckWaitlist(ticket.Key) if err != nil { log.Fatalf("waitlist check failed: %v", err) } if statusCode == 200 { fmt.Println("Ticket is valid, proceed with API call") } else { fmt.Printf("Still in queue, HTTP status: %d\n", statusCode) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.