github.com/lirm/aeron-go@v0.0.0-20230415210743-920325491dc4/aeron/counters/counters.go (about)

     1  /*
     2  Copyright 2016-2018 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 counters
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  
    23  	"github.com/lirm/aeron-go/aeron/logging"
    24  
    25  	"github.com/lirm/aeron-go/aeron/atomic"
    26  	"github.com/lirm/aeron-go/aeron/flyweight"
    27  	"github.com/lirm/aeron-go/aeron/util"
    28  	"github.com/lirm/aeron-go/aeron/util/memmap"
    29  )
    30  
    31  var logger = logging.MustGetLogger("counters")
    32  
    33  const (
    34  	CncFile                 = "cnc.dat"
    35  	CurrentCncVersion int32 = 512 // util.SemanticVersionCompose(0, 2, 0)
    36  )
    37  
    38  /**
    39   * Description of the command and control file used between driver and clients.
    40   * <p>
    41   * File Layout
    42   * <pre>
    43   *  +-----------------------------+
    44   *  |          Meta Data          |
    45   *  +-----------------------------+
    46   *  |      to-driver Buffer       |
    47   *  +-----------------------------+
    48   *  |      to-clients Buffer      |
    49   *  +-----------------------------+
    50   *  |   Counters Metadata Buffer  |
    51   *  +-----------------------------+
    52   *  |    Counters Values Buffer   |
    53   *  +-----------------------------+
    54   *  |          Error Log          |
    55   *  +-----------------------------+
    56   * </pre>
    57   * <p>
    58   * Meta Data Layout (CnC Version 0.2.0 => 512)
    59   * <pre>
    60   *   0                   1                   2                   3
    61   *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    62   *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    63   *  |                      Aeron CnC Version                        |
    64   *  +---------------------------------------------------------------+
    65   *  |                   to-driver buffer length                     |
    66   *  +---------------------------------------------------------------+
    67   *  |                  to-clients buffer length                     |
    68   *  +---------------------------------------------------------------+
    69   *  |               Counters Metadata buffer length                 |
    70   *  +---------------------------------------------------------------+
    71   *  |                Counters Values buffer length                  |
    72   *  +---------------------------------------------------------------+
    73   *  |                   Error Log buffer length                     |
    74   *  +---------------------------------------------------------------+
    75   *  |                   Client Liveness Timeout                     |
    76   *  |                                                               |
    77   *  +---------------------------------------------------------------+
    78   *  |                    Driver Start Timestamp                     |
    79   *  |                                                               |
    80   *  +---------------------------------------------------------------+
    81   *  |                         Driver PID                            |
    82   *  |                                                               |
    83   *  +---------------------------------------------------------------+
    84   * </pre>
    85   *
    86   * See also <a href="https://github.com/real-logic/aeron/blob/master/aeron-client/src/main/cpp/CncFileDescriptor.h">CncFileDescriptor.h</a>.
    87   */
    88  type MetaDataFlyweight struct {
    89  	flyweight.FWBase
    90  
    91  	CncVersion flyweight.Int32Field
    92  
    93  	toDriverBufLen       flyweight.Int32Field
    94  	toClientBufLen       flyweight.Int32Field
    95  	metadataBufLen       flyweight.Int32Field
    96  	valuesBufLen         flyweight.Int32Field
    97  	errorLogLen          flyweight.Int32Field
    98  	ClientLivenessTo     flyweight.Int64Field
    99  	DriverStartTimestamp flyweight.Int64Field
   100  	DriverPid            flyweight.Int64Field
   101  
   102  	ToDriverBuf  flyweight.RawDataField
   103  	ToClientsBuf flyweight.RawDataField
   104  	MetaDataBuf  flyweight.RawDataField
   105  	ValuesBuf    flyweight.RawDataField
   106  	ErrorBuf     flyweight.RawDataField
   107  }
   108  
   109  func (m *MetaDataFlyweight) Wrap(buf *atomic.Buffer, offset int) flyweight.Flyweight {
   110  	pos := offset
   111  	pos += m.CncVersion.Wrap(buf, pos)
   112  	pos += m.toDriverBufLen.Wrap(buf, pos)
   113  	pos += m.toClientBufLen.Wrap(buf, pos)
   114  	pos += m.metadataBufLen.Wrap(buf, pos)
   115  	pos += m.valuesBufLen.Wrap(buf, pos)
   116  	pos += m.errorLogLen.Wrap(buf, pos)
   117  	pos += m.ClientLivenessTo.Wrap(buf, pos)
   118  	pos += m.DriverStartTimestamp.Wrap(buf, pos)
   119  	pos += m.DriverPid.Wrap(buf, pos)
   120  
   121  	pos = int(util.AlignInt32(int32(pos), util.CacheLineLength*2))
   122  
   123  	pos += m.ToDriverBuf.Wrap(buf, pos, m.toDriverBufLen.Get())
   124  	pos += m.ToClientsBuf.Wrap(buf, pos, m.toClientBufLen.Get())
   125  	pos += m.MetaDataBuf.Wrap(buf, pos, m.metadataBufLen.Get())
   126  	pos += m.ValuesBuf.Wrap(buf, pos, m.valuesBufLen.Get())
   127  	pos += m.ErrorBuf.Wrap(buf, pos, m.errorLogLen.Get())
   128  
   129  	m.SetSize(pos - offset)
   130  	return m
   131  }
   132  
   133  func MapFile(filename string) (*MetaDataFlyweight, *memmap.File, error) {
   134  
   135  	logger.Debugf("Trying to map file: %s", filename)
   136  	cncMap, err := memmap.MapExisting(filename, 0, 0)
   137  	if err != nil {
   138  		return nil, nil, err
   139  	}
   140  
   141  	cncBuffer := atomic.MakeBuffer(cncMap.GetMemoryPtr(), cncMap.GetMemorySize())
   142  	var meta MetaDataFlyweight
   143  	meta.Wrap(cncBuffer, 0)
   144  
   145  	cncVer := meta.CncVersion.Get()
   146  	logger.Debugf("Mapped %s for ver %d", filename, cncVer)
   147  
   148  	if CurrentCncVersion != cncVer {
   149  		return nil, nil, errors.New(fmt.Sprintf("aeron cnc file version not understood: version=%d", cncVer))
   150  	}
   151  
   152  	return &meta, cncMap, nil
   153  }