github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/examples/pong/pong.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  	"flag"
    21  	"fmt"
    22  	"os"
    23  	"os/signal"
    24  	"runtime/pprof"
    25  	"syscall"
    26  	"time"
    27  
    28  	"github.com/lirm/aeron-go/aeron"
    29  	"github.com/lirm/aeron-go/aeron/atomic"
    30  	"github.com/lirm/aeron-go/aeron/idlestrategy"
    31  	"github.com/lirm/aeron-go/aeron/logbuffer"
    32  	"github.com/lirm/aeron-go/aeron/logging"
    33  	"github.com/lirm/aeron-go/examples"
    34  )
    35  
    36  var logger = logging.MustGetLogger("examples")
    37  
    38  func main() {
    39  
    40  	flag.Parse()
    41  
    42  	if !*examples.ExamplesConfig.LoggingOn {
    43  		logging.SetLevel(logging.INFO, "aeron")
    44  		logging.SetLevel(logging.INFO, "memmap")
    45  		logging.SetLevel(logging.INFO, "driver")
    46  		logging.SetLevel(logging.INFO, "counters")
    47  		logging.SetLevel(logging.INFO, "logbuffers")
    48  		logging.SetLevel(logging.INFO, "buffer")
    49  		logging.SetLevel(logging.INFO, "examples")
    50  	}
    51  
    52  	to := time.Duration(time.Millisecond.Nanoseconds() * *examples.ExamplesConfig.DriverTo)
    53  	ctx := aeron.NewContext().AeronDir(*examples.ExamplesConfig.AeronPrefix).MediaDriverTimeout(to).
    54  		ErrorHandler(func(err error) {
    55  			logger.Fatalf("Received error: %v", err)
    56  		})
    57  
    58  	a, err := aeron.Connect(ctx)
    59  	if err != nil {
    60  		logger.Fatalf("Failed to connect to driver: %s\n", err.Error())
    61  	}
    62  	defer a.Close()
    63  
    64  	subscription, err := a.AddSubscription(*examples.PingPongConfig.PingChannel, int32(*examples.PingPongConfig.PingStreamID))
    65  	if err != nil {
    66  		logger.Fatal(err)
    67  	}
    68  	defer subscription.Close()
    69  	logger.Infof("Subscription found %v", subscription)
    70  
    71  	publication, err := a.AddPublication(*examples.PingPongConfig.PongChannel, int32(*examples.PingPongConfig.PongStreamID))
    72  	if err != nil {
    73  		logger.Fatal(err)
    74  	}
    75  	defer publication.Close()
    76  	logger.Infof("Publication found %v", publication)
    77  
    78  	logger.Infof("ChannelStatusID: %v", publication.ChannelStatusID())
    79  
    80  	logger.Infof("%v", examples.ExamplesConfig)
    81  
    82  	if *examples.ExamplesConfig.ProfilerEnabled {
    83  		fname := fmt.Sprintf("pong-%d.pprof", time.Now().Unix())
    84  		logger.Infof("Profiling enabled. Will use: %s", fname)
    85  		f, err := os.Create(fname)
    86  		if err == nil {
    87  			pprof.StartCPUProfile(f)
    88  			defer pprof.StopCPUProfile()
    89  		} else {
    90  			logger.Infof("Failed to create profile file with %v", err)
    91  		}
    92  	}
    93  
    94  	sigs := make(chan os.Signal, 1)
    95  	done := make(chan bool, 1)
    96  	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    97  	go func() {
    98  		<-sigs
    99  		done <- true
   100  	}()
   101  
   102  	handler := func(buffer *atomic.Buffer, offset int32, length int32, header *logbuffer.Header) {
   103  		if logger.IsEnabledFor(logging.DEBUG) {
   104  			logger.Debugf("Received message at offset %d, length %d, position %d, termId %d, frame len %d",
   105  				offset, length, header.Offset(), header.TermId(), header.FrameLength())
   106  		}
   107  		for true {
   108  			ret := publication.Offer(buffer, offset, length, nil)
   109  			if ret >= 0 {
   110  				break
   111  				//} else {
   112  				//	panic(fmt.Sprintf("Failed to send message of %d bytes due to %d", length, ret))
   113  			}
   114  		}
   115  	}
   116  
   117  	go func() {
   118  		idleStrategy := idlestrategy.Busy{}
   119  		for {
   120  			fragmentsRead := subscription.Poll(handler, 10)
   121  			idleStrategy.Idle(fragmentsRead)
   122  		}
   123  	}()
   124  
   125  	<-done
   126  	logger.Infof("Terminating")
   127  }