github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/cmd/fastcache1e6/prod_shm.go (about)

     1  // install https://github.com/angenalZZZ/doc-zip/raw/master/nanomsg-mingw64.7z
     2  // go get github.com/op/go-nanomsg
     3  // INPROC - transport within a process (between threads, modules etc.)
     4  // IPC - transport between processes on a single machine
     5  // TCP - network transport via TCP
     6  // WS - websockets over TCP
     7  
     8  package main
     9  
    10  import (
    11  	"bytes"
    12  	"fmt"
    13  	"github.com/angenalZZZ/gofunc/data/shm"
    14  	"github.com/angenalZZZ/gofunc/f"
    15  	"github.com/op/go-nanomsg"
    16  	"io"
    17  	"strings"
    18  	"syscall"
    19  	"time"
    20  )
    21  
    22  func ProdSHM() {
    23  	const headSize = 4
    24  	addr := *flagAddr
    25  	if addr == "" {
    26  		_ = fmt.Errorf("Io2SHM fail to check the server address -a has prefix ipc://\n")
    27  		return
    28  	}
    29  
    30  	if strings.HasPrefix(addr, "ipc://") {
    31  		// github.com/op/go-nanomsg
    32  		var (
    33  			err error
    34  			rep *nanomsg.Socket
    35  		)
    36  
    37  		if rep, err = nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.REP); err != nil {
    38  			_ = fmt.Errorf("Io2SHM fail to create shared memory: %v\n", err)
    39  			return
    40  		}
    41  		if _, err = rep.Bind(addr); err != nil {
    42  			_ = fmt.Errorf("Io2SHM fail to create shared memory: %v\n", err)
    43  			return
    44  		}
    45  
    46  		defer func() { _ = rep.Close() }()
    47  		if err = rep.SetRecvTimeout(time.Millisecond); err != nil {
    48  			return
    49  		}
    50  
    51  		for {
    52  			if payload, err := rep.Recv(0); err != nil {
    53  				if err == syscall.ETIMEDOUT || err == io.EOF {
    54  					continue
    55  				}
    56  				_ = fmt.Errorf("Io2SHM failed to Read: %v\n", err)
    57  			} else if len(payload) > headSize {
    58  				if *flagData > 0 {
    59  					fmt.Printf("Io2SHM Recv %q\n", string(payload))
    60  				}
    61  				result := defaultService.Handle(payload)
    62  				if _, err = rep.Send(result, 0); err != nil {
    63  					_ = fmt.Errorf("Io2SHM failed to Write: %v\n", err)
    64  				} else if *flagData > 0 {
    65  					fmt.Printf("Io2SHM Send %q\n", string(result))
    66  				}
    67  			}
    68  		}
    69  	} else {
    70  		// github.com/angenalZZZ/gofunc/data/shm
    71  		size := int32(1) << *flagCont
    72  		if size < 2048 || size > 2097152 {
    73  			size = int32(2097152)
    74  		}
    75  
    76  		initHead := make([]byte, headSize)
    77  		zeroHead := f.BytesRepeat('0', headSize)
    78  		writeOff := int64(size / 2)
    79  
    80  		m, err := shm.Create(addr, size)
    81  		if err != nil {
    82  			_ = fmt.Errorf("Io2SHM fail to create shared memory: %v\n", err)
    83  
    84  			m, err = shm.Open(addr, size)
    85  			if err != nil {
    86  				_ = fmt.Errorf("Io2SHM fail to open shared memroy: %v\n", err)
    87  				return
    88  			}
    89  		}
    90  		fmt.Printf("Io2SHM server is listening on %s\n", addr)
    91  		for {
    92  			buf := make([]byte, headSize)
    93  			n, err := m.ReadAt(buf, 0)
    94  			if err != nil && err != io.EOF {
    95  				_ = fmt.Errorf("Io2SHM failed to Read: %v\n", err)
    96  				continue
    97  			}
    98  			if bytes.Equal(buf, initHead) || bytes.Equal(buf, zeroHead) {
    99  				time.Sleep(time.Nanosecond)
   100  				continue
   101  			}
   102  			fmt.Printf("%d< %s\n", 0, buf)
   103  
   104  			buf = make([]byte, 80)
   105  			n, _ = m.ReadAt(buf, 0)
   106  			payload := make([]byte, n)
   107  			copy(payload, buf)
   108  			fmt.Printf("%d<< %s\n", 0, payload)
   109  
   110  			buf1 := f.BytesRepeat('0', headSize)
   111  			if n, err := m.WriteAt(buf1, 0); err != nil {
   112  				_ = fmt.Errorf("Io2SHM failed to Write: %v\n", err)
   113  			} else {
   114  				fmt.Printf("%d> %s > len(%d)\n", 0, buf1, n)
   115  			}
   116  			buf2 := make([]byte, 80)
   117  			if n, err := m.ReadAt(buf2, 0); err != nil && err != io.EOF {
   118  				_ = fmt.Errorf("Io2SHM failed to Read: %v\n", err)
   119  				continue
   120  			} else {
   121  				fmt.Printf("%d<< %s > len(%d)\n", 0, buf2, n)
   122  			}
   123  
   124  			result := defaultService.Handle(payload)
   125  			if _, err := m.WriteAt(result, writeOff); err != nil {
   126  				_ = fmt.Errorf("Io2SHM failed to Write: %v\n", err)
   127  			} else {
   128  				fmt.Printf("%d>> %s\n", writeOff, result)
   129  			}
   130  			return
   131  		}
   132  	}
   133  }