github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/examples/basic_rpc/client/basic_client.go (about)

     1  /*
     2  Copyright 2016 Stanislav Liberman
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"flag"
    22  	"fmt"
    23  	"log"
    24  	"os"
    25  	"os/signal"
    26  	"syscall"
    27  	"time"
    28  
    29  	"github.com/lirm/aeron-go/aeron"
    30  	"github.com/lirm/aeron-go/aeron/atomic"
    31  	"github.com/lirm/aeron-go/aeron/idlestrategy"
    32  	"github.com/lirm/aeron-go/aeron/logbuffer"
    33  	"github.com/lirm/aeron-go/aeron/logging"
    34  	"github.com/lirm/aeron-go/examples"
    35  )
    36  
    37  var logger = logging.MustGetLogger("basic_client")
    38  
    39  var interrupt = make(chan os.Signal, 1)
    40  
    41  func init() {
    42  	signal.Notify(interrupt, os.Interrupt)
    43  	signal.Notify(interrupt, syscall.SIGTERM)
    44  }
    45  
    46  func main() {
    47  	flag.Parse()
    48  
    49  	if *examples.ExamplesConfig.LoggingOn {
    50  		logging.SetLevel(logging.INFO, "aeron")
    51  		logging.SetLevel(logging.INFO, "memmap")
    52  		logging.SetLevel(logging.INFO, "driver")
    53  		logging.SetLevel(logging.INFO, "counters")
    54  		logging.SetLevel(logging.INFO, "logbuffers")
    55  		logging.SetLevel(logging.INFO, "buffer")
    56  		logging.SetLevel(logging.INFO, "rb")
    57  	}
    58  
    59  	errorHandler := func(err error) {
    60  		logger.Warning(err)
    61  	}
    62  	to := time.Duration(time.Millisecond.Nanoseconds() * *examples.ExamplesConfig.DriverTo)
    63  	ctx := aeron.NewContext().AeronDir(*examples.ExamplesConfig.AeronPrefix).MediaDriverTimeout(to).ErrorHandler(errorHandler)
    64  
    65  	a, err := aeron.Connect(ctx)
    66  	if err != nil {
    67  		logger.Fatalf("Failed to connect to media driver: %s\n", err.Error())
    68  	}
    69  	defer a.Close()
    70  
    71  	subscription, err := a.AddSubscription("aeron:udp?endpoint=localhost:0", int32(*examples.ExamplesConfig.StreamID))
    72  	if err != nil {
    73  		logger.Fatal(err)
    74  	}
    75  	defer subscription.Close()
    76  
    77  	var subChannel string
    78  	for subChannel == "" {
    79  		subChannel = subscription.ResolvedEndpoint()
    80  		select {
    81  		case <-interrupt:
    82  			return
    83  		default:
    84  			time.Sleep(100 * time.Millisecond)
    85  		}
    86  	}
    87  
    88  	subChannel = "aeron:udp?endpoint=" + subChannel
    89  	log.Printf("Using resolved subscription address %s", subChannel)
    90  
    91  	publication, err := a.AddExclusivePublication(*examples.ExamplesConfig.Channel, int32(*examples.ExamplesConfig.StreamID))
    92  	if err != nil {
    93  		logger.Fatal(err)
    94  	}
    95  	defer publication.Close()
    96  
    97  	for {
    98  		counter := 0
    99  		srcBuffer := atomic.MakeBuffer([]byte(subChannel), len(subChannel))
   100  		ret := publication.Offer(srcBuffer, 0, srcBuffer.Capacity(), nil)
   101  		success := false
   102  		switch ret {
   103  		case aeron.NotConnected:
   104  			log.Printf("%d: not connected yet", counter)
   105  		case aeron.BackPressured:
   106  			log.Printf("%d: back pressured", counter)
   107  		default:
   108  			if ret < 0 {
   109  				log.Printf("%d: Unrecognized code: %d", counter, ret)
   110  			} else {
   111  				log.Printf("%d: success!", counter)
   112  				success = true
   113  			}
   114  		}
   115  
   116  		if success {
   117  			break
   118  		}
   119  
   120  		select {
   121  		case <-interrupt:
   122  			return
   123  		default:
   124  			time.Sleep(100 * time.Millisecond)
   125  		}
   126  	}
   127  
   128  	tmpBuf := &bytes.Buffer{}
   129  	counter := 1
   130  	handler := func(buffer *atomic.Buffer, offset int32, length int32, header *logbuffer.Header) {
   131  		bytes := buffer.GetBytesArray(offset, length)
   132  		tmpBuf.Reset()
   133  		buffer.WriteBytes(tmpBuf, offset, length)
   134  		fmt.Printf("%8.d: Gots me a fragment offset:%d length: %d payload: %s (buf:%s)\n", counter, offset, length, string(bytes), string(tmpBuf.Next(int(length))))
   135  
   136  		counter++
   137  	}
   138  
   139  	idleStrategy := idlestrategy.Sleeping{SleepFor: time.Millisecond}
   140  
   141  	for {
   142  		fragmentsRead := subscription.Poll(handler, 10)
   143  		select {
   144  		case <-interrupt:
   145  			return
   146  		default:
   147  		}
   148  		idleStrategy.Idle(fragmentsRead)
   149  
   150  	}
   151  }