Skip to content

Commit

Permalink
test: add an example for netpoll package
Browse files Browse the repository at this point in the history
  • Loading branch information
panjf2000 committed Jan 5, 2025
1 parent 1de2082 commit c669a9d
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 2 deletions.
155 changes: 155 additions & 0 deletions pkg/netpoll/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2025 The Gnet Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package netpoll_test

import (
"context"
"fmt"
"net"
"os"
"os/signal"
"time"

"github.com/panjf2000/gnet/v2/pkg/errors"
"github.com/panjf2000/gnet/v2/pkg/netpoll"
)

func Example() {
ln, err := net.Listen("tcp", "127.0.0.1:9090")
if err != nil {
panic(fmt.Sprintf("Error listening: %v", err))
}

defer ln.Close()

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer cancel()

go func() {
c, err := ln.Accept()
if err != nil {
panic(fmt.Sprintf("Error accepting connection: %v", err))
}

defer c.Close()

buf := make([]byte, 64)

for {
select {
case <-ctx.Done():
cancel()
fmt.Printf("Signal received: %v\n", ctx.Err())
return
default:
}

_, err := c.Read(buf)
if err != nil {
panic(fmt.Sprintf("Error reading data from client: %v", err))
}
fmt.Printf("Received data from client: %s\n", buf)

_, err = c.Write([]byte("Hello, client!"))
if err != nil {
panic(fmt.Sprintf("Error writing data to client: %v", err))
}
fmt.Println("Sent data to client")

time.Sleep(200 * time.Millisecond)
}
}()

// Wait for the server to start running.
time.Sleep(500 * time.Millisecond)

poller, err := netpoll.OpenPoller()

Check failure on line 80 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.OpenPoller

Check failure on line 80 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.OpenPoller

Check failure on line 80 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.OpenPoller

Check failure on line 80 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.OpenPoller
if err != nil {
panic(fmt.Sprintf("Error opening poller: %v", err))
}

defer poller.Close()

addr, err := net.ResolveTCPAddr("tcp", ln.Addr().String())
if err != nil {
panic(fmt.Sprintf("Error resolving TCP address: %v", err))
}
c, err := net.DialTCP("tcp", nil, addr)
if err != nil {
panic(fmt.Sprintf("Error dialing TCP address: %v", err))
}

f, err := c.File()
if err != nil {
panic(fmt.Sprintf("Error getting file from connection: %v", err))
}

closeClient := func() {
c.Close()
f.Close()
}
defer closeClient()

sendData := true

pa := netpoll.PollAttachment{

Check failure on line 109 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.PollAttachment

Check failure on line 109 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.PollAttachment

Check failure on line 109 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.PollAttachment

Check failure on line 109 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.PollAttachment
FD: int(f.Fd()),
Callback: func(fd int, event netpoll.IOEvent, flags netpoll.IOFlags) error { //nolint:revive

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 111 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOFlags
if netpoll.IsErrorEvent(event, flags) {

Check failure on line 112 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsErrorEvent

Check failure on line 112 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsErrorEvent

Check failure on line 112 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsErrorEvent

Check failure on line 112 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsErrorEvent
closeClient()
return errors.ErrEngineShutdown
}

if netpoll.IsReadEvent(event) {

Check failure on line 117 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsReadEvent

Check failure on line 117 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsReadEvent

Check failure on line 117 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsReadEvent

Check failure on line 117 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsReadEvent
buf := make([]byte, 64)
_, err := c.Read(buf)
if err != nil {
closeClient()
fmt.Println("Error reading data from server:", err)
return errors.ErrEngineShutdown
}
fmt.Printf("Received data from server: %s\n", buf)
sendData = true
// Process the data...
}

if netpoll.IsWriteEvent(event) && sendData {

Check failure on line 130 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsWriteEvent

Check failure on line 130 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsWriteEvent

Check failure on line 130 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IsWriteEvent

Check failure on line 130 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IsWriteEvent
sendData = false
// Write data to the connection...
_, err := c.Write([]byte("Hello, server!"))
if err != nil {
closeClient()
fmt.Println("Error writing data to server:", err)
return errors.ErrEngineShutdown
}
fmt.Println("Sent data to server")
}

return nil
},
}

if err := poller.AddReadWrite(&pa, false); err != nil {
panic(fmt.Sprintf("Error adding file descriptor to poller: %v", err))
}

err = poller.Polling(func(fd int, event netpoll.IOEvent, flags netpoll.IOFlags) error {

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.20 @ windows-latest

undefined: netpoll.IOFlags

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOEvent

Check failure on line 150 in pkg/netpoll/example_test.go

View workflow job for this annotation

GitHub Actions / Go 1.23 @ windows-latest

undefined: netpoll.IOFlags
return pa.Callback(fd, event, flags)
})

fmt.Printf("Poller exited with error: %v", err)
}
12 changes: 10 additions & 2 deletions pkg/netpoll/netpoll.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,23 @@ The OpenPoller function creates a new Poller instance:
c.Close()
f.Close()
}
defer closeClient()
The PollAttachment consists of a file descriptor and its callback function.
PollAttachment is used to register a file descriptor with the Poller.
The callback function is called when an event occurs on the file descriptor:
pa := netpoll.PollAttachment{
FD: int(f.Fd()),
Callback: func(i int, event netpoll.IOEvent, flags netpoll.IOFlags) error {
Callback: func(fd int, event netpoll.IOEvent, flags netpoll.IOFlags) error {
if netpoll.IsErrorEvent(event, flags) {
closeClient()
return errors.ErrEngineShutdown
}
if netpoll.IsReadEvent(event) {
buf := make([]byte, 64)
// Read data from the connection.
_, err := c.Read(buf)
if err != nil {
closeClient()
Expand All @@ -76,7 +78,7 @@ The callback function is called when an event occurs on the file descriptor:
}
if netpoll.IsWriteEvent(event) {
// Write data to the connection...
// Write data to the connection.
_, err := c.Write([]byte("hello"))
if err != nil {
closeClient()
Expand All @@ -97,5 +99,11 @@ waiting for I/O events to occur:
poller.Polling(func(fd int, event netpoll.IOEvent, flags netpoll.IOFlags) error {
return pa.Callback(fd, event, flags)
})
Or
poller.Polling()
if you've enabled the build tag `poll_opt`.
*/
package netpoll

0 comments on commit c669a9d

Please sign in to comment.