问:
Why does my gnuradio Python module run when I load the flowgraph instead of when I click the start button?
This is gnuradio v3.8.5.0 running under Ubuntu 22.04, and I am having problems with something that used to work (previous version of O/S [Ubuntu 20.10] and gnuradio). I have a Python module that uses the serial port to connect to an Adafruit GPS device, which gets the latitude and longitude and makes it available to the gnuradio flowgraph. Previously, the Python module started running when I load the flowgraph into gnuradio-companion and click the start button (black triangle). Now, the Python module starts running immediately when I load the flowgraph, and blocks the flowgraph from further action, as it contains a loop to get time updates from the GPS. Further, the block that needs the data can't find the Python module; I notice that whenever I edit the Python module, the editor saves the module into /tmp.  I can't find any documentation that explains how this is now working... can anyone help?

I tried changing the name of the Python module and re-saving it, but get the same result.

Here is the grc:

```<code>options:
  parameters:
    author: ''
    category: '[GRC Hier Blocks]'
    cmake_opt: ''
    comment: ''
    copyright: ''
    description: ''
    gen_cmake: 'On'
    gen_linking: dynamic
    generate_options: qt_gui
    hier_block_src_path: '.:'
    id: grape_GPS_DRF
    max_nouts: '0'
    output_language: python
    placement: (0,0)
    qt_qss_theme: ''
    realtime_scheduling: ''
    run: 'True'
    run_command: '{python} -u {filename}'
    run_options: prompt
    sizing_mode: fixed
    thread_safe_setters: ''
    title: Grape19, 5 MHz
    window_size: (1000,1000)
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [8, 8]
    rotation: 0
    state: enabled

blocks:
- name: decimation
  id: variable
  parameters:
    comment: ''
    value: '800'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [393, 21]
    rotation: 0
    state: true
- name: samp_rate
  id: variable
  parameters:
    comment: ''
    value: '8000'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [184, 12]
    rotation: 0
    state: enabled
- name: analog_sig_source_x_0
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: '-1000'
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: samp_rate
    type: complex
    waveform: analog.GR_COS_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [106, 323]
    rotation: 0
    state: enabled
- name: audio_source_0
  id: audio_source
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    device_name: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_outputs: '1'
    ok_to_block: 'True'
    samp_rate: samp_rate
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [58, 113]
    rotation: 0
    state: true
- name: blocks_float_to_complex_0
  id: blocks_float_to_complex
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [322, 95]
    rotation: 0
    state: disabled
- name: blocks_multiply_xx_0
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: complex
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [348, 326]
    rotation: 0
    state: enabled
- name: gr_digital_rf_digital_rf_channel_sink_0
  id: gr_digital_rf_digital_rf_channel_sink
  parameters:
    affinity: ''
    alias: ''
    center_freqs: '[5.0]'
    checksum: 'False'
    comment: ''
    compression_level: '1'
    debug: 'False'
    dir: /media/guser/seagate1/wide/ch0
    file_cadence_ms: '1000'
    ignore_tags: 'False'
    input: fc32
    is_continuous: 'True'
    marching_periods: 'True'
    metadata: '{''lat'':unixtime_module.latitude,''long'':unixtime_module.longitude}'
    min_chunksize: '0'
    sample_rate_denominator: '1'
    sample_rate_numerator: int(samp_rate)
    start: unixtime_module.timestamp * samp_rate
    stop_on_skipped: 'False'
    stop_on_time_tag: 'False'
    subdir_cadence_s: '3600'
    uuid: grape19
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [638, 38]
    rotation: 0
    state: disabled
- name: gr_digital_rf_digital_rf_channel_sink_0_0
  id: gr_digital_rf_digital_rf_channel_sink
  parameters:
    affinity: ''
    alias: ''
    center_freqs: '[5.0]'
    checksum: 'False'
    comment: ''
    compression_level: '1'
    debug: 'False'
    dir: /media/guser/RFdata/narrow16/ch0
    file_cadence_ms: '60000'
    ignore_tags: 'False'
    input: fc32
    is_continuous: 'True'
    marching_periods: 'True'
    metadata: '{''lat'':unixtime_module.latitude,''long'':unixtime_module.longitude}'
    min_chunksize: '0'
    sample_rate_denominator: '1'
    sample_rate_numerator: int(samp_rate/decimation)
    start: unixtime_module.timestamp * (samp_rate/(10*decimation))
    stop_on_skipped: 'False'
    stop_on_time_tag: 'False'
    subdir_cadence_s: '3600'
    uuid: grape19
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [691, 443]
    rotation: 0
    state: enabled
- name: hilbert_fc_0
  id: hilbert_fc
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_taps: '512'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [139, 248]
    rotation: 0
    state: true
- name: import_0
  id: import
  parameters:
    alias: ''
    comment: ''
    imports: import time
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [294, 16]
    rotation: 0
    state: true
- name: low_pass_filter_0
  id: low_pass_filter
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    cutoff_freq: '50'
    decim: decimation
    gain: '1'
    interp: '1'
    maxoutbuf: '0'
    minoutbuf: '0'
    samp_rate: samp_rate
    type: fir_filter_ccf
    width: '5'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [473, 297]
    rotation: 0
    state: true
- name: qtgui_waterfall_sink_x_0
  id: qtgui_waterfall_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    axislabels: 'True'
    bw: samp_rate
    color1: '0'
    color10: '0'
    color2: '0'
    color3: '0'
    color4: '0'
    color5: '0'
    color6: '0'
    color7: '0'
    color8: '0'
    color9: '0'
    comment: ''
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    int_max: '10'
    int_min: '-140'
    label1: ''
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: '""'
    nconnections: '1'
    showports: 'False'
    type: complex
    update_time: '0.10'
    wintype: firdes.WIN_BLACKMAN_hARRIS
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [644, 166]
    rotation: 0
    state: disabled
- name: qtgui_waterfall_sink_x_0_0
  id: qtgui_waterfall_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    axislabels: 'True'
    bw: samp_rate/decimation
    color1: '0'
    color10: '0'
    color2: '0'
    color3: '0'
    color4: '0'
    color5: '0'
    color6: '0'
    color7: '0'
    color8: '0'
    color9: '0'
    comment: ''
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    int_max: '10'
    int_min: '-140'
    label1: ''
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: '""'
    nconnections: '1'
    showports: 'False'
    type: complex
    update_time: '0.10'
    wintype: firdes.WIN_BLACKMAN_hARRIS
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [723, 320]
    rotation: 0
    state: true
- name: unixtime_module
  id: epy_module
  parameters:
    alias: ''
    comment: ''
    source_code: "# this module will be imported in the into your flowgraph\n# Author;\
      \ W. Engelke, AB4EJ\n# This tries to read date, time, lat, long from Adafruit\
      \ GPS hat for use in\n# seting the start time of Digital RF dataset. If no response\
      \ from serial port,\n# defaults to using system time. \nimport serial\nimport\
      \ datetime\nimport time\nfrom datetime import timezone\n\nser = serial.Serial(port='/dev/serial0',baudrate=9600,\n\
      \ parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,\n bytesize=serial.EIGHTBITS,timeout=1,write_timeout=1)\n\
      ser.close()\nser.open()\n\nz=1\nwhile z==1:\n  x=ser.readline()\n  print(\"\
      Received \",len(x),\" bytes\")\n  if(len(x) == 0):\n    print(\"No serial response\
      \ from GPS card, defaulting to system time & location.\")\n    timestamp = int(time.time())\n\
      \    print(timestamp)\n    latitude = 0.0\n    longitude = 0.0\n    z = 0 #\
      \ drop out of loop and thus out of this module\n  else:\n    reading = x.split(b\"\
      ,\")\n\n    if reading[0] == b\"$GPRMC\" or reading[0] == b\"$GNRMC\" :\n  \
      \    print(\"found GPRMC *********************\")\n      print(\"time=\",reading[1].decode()+\"\
      Z\",\" lat=\",reading[3],reading[4],\" long=\",reading[5],reading[6],\" date=\"\
      ,reading[9])\n      if reading[3] == b'':  # GPS apparently does not have a\
      \ fix; set defaults\n        print(\"No GPS data; using defaults\")\n      \
      \  latitude = 0\n        longitude = 0\n        timestamp = int(time.time())\
      \ # use time from system clock, precision to 1 sec.\n        print(\"timestamp=\"\
      ,timestamp)\n        z = 0\n      else:\n        latitude = float(reading[3][0:2])\
      \ + float(reading[3][2:10])/60\n        if reading[4] == b\"S\":\n         \
      \ latitude = -latitude\n        print(\"latitude=\",latitude)\n      \n    \
      \    longitude = float(reading[5][0:3]) + float(reading[5][3:11])/60\n     \
      \   if reading[6] == b\"W\" :\n          longitude = -longitude\n        print(\"\
      longitude=\",longitude)\n\n        hour =       (float(reading[1].decode())\
      \ - (float(reading[1].decode()))%10000)/10000\n        minute =     ((float(reading[1].decode())\
      \ - (float(reading[1].decode()))%100)/100) - 100*hour\n        second =    \
      \  float(reading[1].decode()) - (hour * 10000) - (minute*100)\n        reading1\
      \ = reading[9].decode()\n        print(\"reading1=\", reading1)\n        DD\
      \ = reading1[0:2]\n        MM = reading1[2:4]\n        YY = int(reading1[4:6])\
      \ + 2000\n        print(\"hour: \", hour, \" minute: \",minute, \" second:\"\
      ,second)\n        print(\"DD \",DD,\" MM \", MM, \" YY \", YY)\n        dt =\
      \ datetime.datetime(int(YY), int(MM), int(DD), int(hour), int(minute), int(second))\n\
      \        timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp())\n    \
      \    print(timestamp)\n        z=0\n    \n"
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [505, 22]
    rotation: 0
    state: enabled

connections:
- [analog_sig_source_x_0, '0', blocks_multiply_xx_0, '1']
- [audio_source_0, '0', blocks_float_to_complex_0, '0']
- [audio_source_0, '0', blocks_float_to_complex_0, '1']
- [audio_source_0, '0', hilbert_fc_0, '0']
- [blocks_float_to_complex_0, '0', gr_digital_rf_digital_rf_channel_sink_0, '0']
- [blocks_float_to_complex_0, '0', qtgui_waterfall_sink_x_0, '0']
- [blocks_multiply_xx_0, '0', low_pass_filter_0, '0']
- [hilbert_fc_0, '0', blocks_multiply_xx_0, '0']
- [low_pass_filter_0, '0', gr_digital_rf_digital_rf_channel_sink_0_0, '0']
- [low_pass_filter_0, '0', qtgui_waterfall_sink_x_0_0, '0']

metadata:
  file_format: 1
</code>```

Here is the code in the Python unixtime_module:

```<code>import serial
import datetime
import time
from datetime import timezone

ser = serial.Serial(port='/dev/serial0',baudrate=9600,
 parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,
 bytesize=serial.EIGHTBITS,timeout=1,write_timeout=1)
ser.close()
ser.open()

z=1
while z==1:
  x=ser.readline()
  print("Received ",len(x)," bytes")
  if(len(x) == 0):
    print("No serial response from GPS card, defaulting to system time & location.")
    timestamp = int(time.time())
    print(timestamp)
    latitude = 0.0
    longitude = 0.0
    z = 0 # drop out of loop and thus out of this module
  else:
    reading = x.split(b",")

    if reading[0] == b"$GPRMC" or reading[0] == b"$GNRMC" :
      print("found GPRMC *********************")
      print("time=",reading[1].decode()+"Z"," lat=",reading[3],reading[4]," long=",reading[5],reading[6]," date=",reading[9])
      if reading[3] == b'':  # GPS apparently does not have a fix; set defaults
        print("No GPS data; using defaults")
        latitude = 0
        longitude = 0
        timestamp = int(time.time()) # use time from system clock, precision to 1 sec.
        print("timestamp=",timestamp)
        z = 0
      else:
        latitude = float(reading[3][0:2]) + float(reading[3][2:10])/60
        if reading[4] == b"S":
          latitude = -latitude
        print("latitude=",latitude)

        longitude = float(reading[5][0:3]) + float(reading[5][3:11])/60
        if reading[6] == b"W" :
          longitude = -longitude
        print("longitude=",longitude)

        hour =       (float(reading[1].decode()) - (float(reading[1].decode()))%10000)/10000
        minute =     ((float(reading[1].decode()) - (float(reading[1].decode()))%100)/100) - 100*hour
        second =      float(reading[1].decode()) - (hour * 10000) - (minute*100)
        reading1 = reading[9].decode()
        print("reading1=", reading1)
        DD = reading1[0:2]
        MM = reading1[2:4]
        YY = int(reading1[4:6]) + 2000
        print("hour: ", hour, " minute: ",minute, " second:",second)
        print("DD ",DD," MM ", MM, " YY ", YY)
        dt = datetime.datetime(int(YY), int(MM), int(DD), int(hour), int(minute), int(second))
        timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp())
        print(timestamp)
        z=0

</code>```

I posted the code as requested, but I don't think this has anything to do with the code, since all the code used to work fine. I have the impression that something related to Python Modules  changed in the most recent version of gnuradio.  Is it perhaps now necessary to put the python module into a specific directory?

Body:
This is gnuradio v3.8.5.0 running under Ubuntu 22.04, and I am having problems with something that used to work (previous version of O/S [Ubuntu 20.10] and gnuradio). I have a Python module that uses the serial port to connect to an Adafruit GPS device, which gets the latitude and longitude and makes it available to the gnuradio flowgraph. Previously, the Python module started running when I load the flowgraph into gnuradio-companion and click the start button (black triangle). Now, the Python module starts running immediately when I load the flowgraph, and blocks the flowgraph from further action, as it contains a loop to get time updates from the GPS. Further, the block that needs the data can't find the Python module; I notice that whenever I edit the Python module, the editor saves the module into /tmp.  I can't find any documentation that explains how this is now working... can anyone help?

I tried changing the name of the Python module and re-saving it, but get the same result.

Here is the grc:

options:
  parameters:
    author: ''
    category: '[GRC Hier Blocks]'
    cmake_opt: ''
    comment: ''
    copyright: ''
    description: ''
    gen_cmake: 'On'
    gen_linking: dynamic
    generate_options: qt_gui
    hier_block_src_path: '.:'
    id: grape_GPS_DRF
    max_nouts: '0'
    output_language: python
    placement: (0,0)
    qt_qss_theme: ''
    realtime_scheduling: ''
    run: 'True'
    run_command: '{python} -u {filename}'
    run_options: prompt
    sizing_mode: fixed
    thread_safe_setters: ''
    title: Grape19, 5 MHz
    window_size: (1000,1000)
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [8, 8]
    rotation: 0
    state: enabled

blocks:
- name: decimation
  id: variable
  parameters:
    comment: ''
    value: '800'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [393, 21]
    rotation: 0
    state: true
- name: samp_rate
  id: variable
  parameters:
    comment: ''
    value: '8000'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [184, 12]
    rotation: 0
    state: enabled
- name: analog_sig_source_x_0
  id: analog_sig_source_x
  parameters:
    affinity: ''
    alias: ''
    amp: '1'
    comment: ''
    freq: '-1000'
    maxoutbuf: '0'
    minoutbuf: '0'
    offset: '0'
    phase: '0'
    samp_rate: samp_rate
    type: complex
    waveform: analog.GR_COS_WAVE
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [106, 323]
    rotation: 0
    state: enabled
- name: audio_source_0
  id: audio_source
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    device_name: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_outputs: '1'
    ok_to_block: 'True'
    samp_rate: samp_rate
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [58, 113]
    rotation: 0
    state: true
- name: blocks_float_to_complex_0
  id: blocks_float_to_complex
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [322, 95]
    rotation: 0
    state: disabled
- name: blocks_multiply_xx_0
  id: blocks_multiply_xx
  parameters:
    affinity: ''
    alias: ''
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_inputs: '2'
    type: complex
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [348, 326]
    rotation: 0
    state: enabled
- name: gr_digital_rf_digital_rf_channel_sink_0
  id: gr_digital_rf_digital_rf_channel_sink
  parameters:
    affinity: ''
    alias: ''
    center_freqs: '[5.0]'
    checksum: 'False'
    comment: ''
    compression_level: '1'
    debug: 'False'
    dir: /media/guser/seagate1/wide/ch0
    file_cadence_ms: '1000'
    ignore_tags: 'False'
    input: fc32
    is_continuous: 'True'
    marching_periods: 'True'
    metadata: '{''lat'':unixtime_module.latitude,''long'':unixtime_module.longitude}'
    min_chunksize: '0'
    sample_rate_denominator: '1'
    sample_rate_numerator: int(samp_rate)
    start: unixtime_module.timestamp * samp_rate
    stop_on_skipped: 'False'
    stop_on_time_tag: 'False'
    subdir_cadence_s: '3600'
    uuid: grape19
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [638, 38]
    rotation: 0
    state: disabled
- name: gr_digital_rf_digital_rf_channel_sink_0_0
  id: gr_digital_rf_digital_rf_channel_sink
  parameters:
    affinity: ''
    alias: ''
    center_freqs: '[5.0]'
    checksum: 'False'
    comment: ''
    compression_level: '1'
    debug: 'False'
    dir: /media/guser/RFdata/narrow16/ch0
    file_cadence_ms: '60000'
    ignore_tags: 'False'
    input: fc32
    is_continuous: 'True'
    marching_periods: 'True'
    metadata: '{''lat'':unixtime_module.latitude,''long'':unixtime_module.longitude}'
    min_chunksize: '0'
    sample_rate_denominator: '1'
    sample_rate_numerator: int(samp_rate/decimation)
    start: unixtime_module.timestamp * (samp_rate/(10*decimation))
    stop_on_skipped: 'False'
    stop_on_time_tag: 'False'
    subdir_cadence_s: '3600'
    uuid: grape19
    vlen: '1'
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [691, 443]
    rotation: 0
    state: enabled
- name: hilbert_fc_0
  id: hilbert_fc
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    maxoutbuf: '0'
    minoutbuf: '0'
    num_taps: '512'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [139, 248]
    rotation: 0
    state: true
- name: import_0
  id: import
  parameters:
    alias: ''
    comment: ''
    imports: import time
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [294, 16]
    rotation: 0
    state: true
- name: low_pass_filter_0
  id: low_pass_filter
  parameters:
    affinity: ''
    alias: ''
    beta: '6.76'
    comment: ''
    cutoff_freq: '50'
    decim: decimation
    gain: '1'
    interp: '1'
    maxoutbuf: '0'
    minoutbuf: '0'
    samp_rate: samp_rate
    type: fir_filter_ccf
    width: '5'
    win: firdes.WIN_HAMMING
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [473, 297]
    rotation: 0
    state: true
- name: qtgui_waterfall_sink_x_0
  id: qtgui_waterfall_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    axislabels: 'True'
    bw: samp_rate
    color1: '0'
    color10: '0'
    color2: '0'
    color3: '0'
    color4: '0'
    color5: '0'
    color6: '0'
    color7: '0'
    color8: '0'
    color9: '0'
    comment: ''
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    int_max: '10'
    int_min: '-140'
    label1: ''
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: '""'
    nconnections: '1'
    showports: 'False'
    type: complex
    update_time: '0.10'
    wintype: firdes.WIN_BLACKMAN_hARRIS
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [644, 166]
    rotation: 0
    state: disabled
- name: qtgui_waterfall_sink_x_0_0
  id: qtgui_waterfall_sink_x
  parameters:
    affinity: ''
    alias: ''
    alpha1: '1.0'
    alpha10: '1.0'
    alpha2: '1.0'
    alpha3: '1.0'
    alpha4: '1.0'
    alpha5: '1.0'
    alpha6: '1.0'
    alpha7: '1.0'
    alpha8: '1.0'
    alpha9: '1.0'
    axislabels: 'True'
    bw: samp_rate/decimation
    color1: '0'
    color10: '0'
    color2: '0'
    color3: '0'
    color4: '0'
    color5: '0'
    color6: '0'
    color7: '0'
    color8: '0'
    color9: '0'
    comment: ''
    fc: '0'
    fftsize: '1024'
    freqhalf: 'True'
    grid: 'False'
    gui_hint: ''
    int_max: '10'
    int_min: '-140'
    label1: ''
    label10: ''
    label2: ''
    label3: ''
    label4: ''
    label5: ''
    label6: ''
    label7: ''
    label8: ''
    label9: ''
    legend: 'True'
    maxoutbuf: '0'
    minoutbuf: '0'
    name: '""'
    nconnections: '1'
    showports: 'False'
    type: complex
    update_time: '0.10'
    wintype: firdes.WIN_BLACKMAN_hARRIS
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [723, 320]
    rotation: 0
    state: true
- name: unixtime_module
  id: epy_module
  parameters:
    alias: ''
    comment: ''
    source_code: "# this module will be imported in the into your flowgraph\n# Author;\
      \ W. Engelke, AB4EJ\n# This tries to read date, time, lat, long from Adafruit\
      \ GPS hat for use in\n# seting the start time of Digital RF dataset. If no response\
      \ from serial port,\n# defaults to using system time. \nimport serial\nimport\
      \ datetime\nimport time\nfrom datetime import timezone\n\nser = serial.Serial(port='/dev/serial0',baudrate=9600,\n\
      \ parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,\n bytesize=serial.EIGHTBITS,timeout=1,write_timeout=1)\n\
      ser.close()\nser.open()\n\nz=1\nwhile z==1:\n  x=ser.readline()\n  print(\"\
      Received \",len(x),\" bytes\")\n  if(len(x) == 0):\n    print(\"No serial response\
      \ from GPS card, defaulting to system time & location.\")\n    timestamp = int(time.time())\n\
      \    print(timestamp)\n    latitude = 0.0\n    longitude = 0.0\n    z = 0 #\
      \ drop out of loop and thus out of this module\n  else:\n    reading = x.split(b\"\
      ,\")\n\n    if reading[0] == b\"$GPRMC\" or reading[0] == b\"$GNRMC\" :\n  \
      \    print(\"found GPRMC *********************\")\n      print(\"time=\",reading[1].decode()+\"\
      Z\",\" lat=\",reading[3],reading[4],\" long=\",reading[5],reading[6],\" date=\"\
      ,reading[9])\n      if reading[3] == b'':  # GPS apparently does not have a\
      \ fix; set defaults\n        print(\"No GPS data; using defaults\")\n      \
      \  latitude = 0\n        longitude = 0\n        timestamp = int(time.time())\
      \ # use time from system clock, precision to 1 sec.\n        print(\"timestamp=\"\
      ,timestamp)\n        z = 0\n      else:\n        latitude = float(reading[3][0:2])\
      \ + float(reading[3][2:10])/60\n        if reading[4] == b\"S\":\n         \
      \ latitude = -latitude\n        print(\"latitude=\",latitude)\n      \n    \
      \    longitude = float(reading[5][0:3]) + float(reading[5][3:11])/60\n     \
      \   if reading[6] == b\"W\" :\n          longitude = -longitude\n        print(\"\
      longitude=\",longitude)\n\n        hour =       (float(reading[1].decode())\
      \ - (float(reading[1].decode()))%10000)/10000\n        minute =     ((float(reading[1].decode())\
      \ - (float(reading[1].decode()))%100)/100) - 100*hour\n        second =    \
      \  float(reading[1].decode()) - (hour * 10000) - (minute*100)\n        reading1\
      \ = reading[9].decode()\n        print(\"reading1=\", reading1)\n        DD\
      \ = reading1[0:2]\n        MM = reading1[2:4]\n        YY = int(reading1[4:6])\
      \ + 2000\n        print(\"hour: \", hour, \" minute: \",minute, \" second:\"\
      ,second)\n        print(\"DD \",DD,\" MM \", MM, \" YY \", YY)\n        dt =\
      \ datetime.datetime(int(YY), int(MM), int(DD), int(hour), int(minute), int(second))\n\
      \        timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp())\n    \
      \    print(timestamp)\n        z=0\n    \n"
  states:
    bus_sink: false
    bus_source: false
    bus_structure: null
    coordinate: [505, 22]
    rotation: 0
    state: enabled

connections:
- [analog_sig_source_x_0, '0', blocks_multiply_xx_0, '1']
- [audio_source_0, '0', blocks_float_to_complex_0, '0']
- [audio_source_0, '0', blocks_float_to_complex_0, '1']
- [audio_source_0, '0', hilbert_fc_0, '0']
- [blocks_float_to_complex_0, '0', gr_digital_rf_digital_rf_channel_sink_0, '0']
- [blocks_float_to_complex_0, '0', qtgui_waterfall_sink_x_0, '0']
- [blocks_multiply_xx_0, '0', low_pass_filter_0, '0']
- [hilbert_fc_0, '0', blocks_multiply_xx_0, '0']
- [low_pass_filter_0, '0', gr_digital_rf_digital_rf_channel_sink_0_0, '0']
- [low_pass_filter_0, '0', qtgui_waterfall_sink_x_0_0, '0']

metadata:
  file_format: 1

Here is the code in the Python unixtime_module:

import serial
import datetime
import time
from datetime import timezone

ser = serial.Serial(port='/dev/serial0',baudrate=9600,
 parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,
 bytesize=serial.EIGHTBITS,timeout=1,write_timeout=1)
ser.close()
ser.open()

z=1
while z==1:
  x=ser.readline()
  print("Received ",len(x)," bytes")
  if(len(x) == 0):
    print("No serial response from GPS card, defaulting to system time & location.")
    timestamp = int(time.time())
    print(timestamp)
    latitude = 0.0
    longitude = 0.0
    z = 0 # drop out of loop and thus out of this module
  else:
    reading = x.split(b",")

    if reading[0] == b"$GPRMC" or reading[0] == b"$GNRMC" :
      print("found GPRMC *********************")
      print("time=",reading[1].decode()+"Z"," lat=",reading[3],reading[4]," long=",reading[5],reading[6]," date=",reading[9])
      if reading[3] == b'':  # GPS apparently does not have a fix; set defaults
        print("No GPS data; using defaults")
        latitude = 0
        longitude = 0
        timestamp = int(time.time()) # use time from system clock, precision to 1 sec.
        print("timestamp=",timestamp)
        z = 0
      else:
        latitude = float(reading[3][0:2]) + float(reading[3][2:10])/60
        if reading[4] == b"S":
          latitude = -latitude
        print("latitude=",latitude)

        longitude = float(reading[5][0:3]) + float(reading[5][3:11])/60
        if reading[6] == b"W" :
          longitude = -longitude
        print("longitude=",longitude)

        hour =       (float(reading[1].decode()) - (float(reading[1].decode()))%10000)/10000
        minute =     ((float(reading[1].decode()) - (float(reading[1].decode()))%100)/100) - 100*hour
        second =      float(reading[1].decode()) - (hour * 10000) - (minute*100)
        reading1 = reading[9].decode()
        print("reading1=", reading1)
        DD = reading1[0:2]
        MM = reading1[2:4]
        YY = int(reading1[4:6]) + 2000
        print("hour: ", hour, " minute: ",minute, " second:",second)
        print("DD ",DD," MM ", MM, " YY ", YY)
        dt = datetime.datetime(int(YY), int(MM), int(DD), int(hour), int(minute), int(second))
        timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp())
        print(timestamp)
        z=0

I posted the code as requested, but I don't think this has anything to do with the code, since all the code used to work fine. I have the impression that something related to Python Modules  changed in the most recent version of gnuradio.  Is it perhaps now necessary to put the python module into a specific directory?


来源: stackexchange

问:
Background message could not be handled in Dart Firebase_messaging^14.2.1
Since the firebase_messaging get ^14.2.1 version I can't find an answer to how can I resolve the problem.

When I send a post from the Postman everything is fine, I get a notification on the blocked phone, but I have an error in the console:

```<code>W/FLTFireMsgService(13437): A background message could not be handled in Dart as no onBackgroundMessage handler has been registered.
W/FirebaseMessaging(13437): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
</code>```

**The Code is implemented **

```<code>import 'dart:io';
import 'package:cholachol_drive/globalvariables.dart';
import 'package:cholachol_drive/main.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

class PushNotificationService {
  FirebaseMessaging fcm = FirebaseMessaging.instance;

  Future initialize(context) async {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('Got a message whilst in the foreground!');
      print('Message data: ${message.data}');

      print('Message also contained a notification: ${message.notification}');
      // if (message.notification != null) {}
    });

//Background
    Future<void> _firebaseMessagingBackgroundHandler(
        RemoteMessage message) async {
      await Firebase.initializeApp();
      print("Handling a background message: ${message.messageId}");
    }
  }

  Future<String> getToken() async {
    String token = await FirebaseMessaging.instance.getToken();
    print("token: $token");

    DatabaseReference tokerRef = FirebaseDatabase.instance
        .ref()
        .child("drivers/${currentFirebaseUser.uid}/token");

    FirebaseMessaging.instance.subscribeToTopic('alldrivers');
    FirebaseMessaging.instance.subscribeToTopic('allusers');
  }

  String getRideID(Map<String, dynamic> message) {
    print("onLaunch: $message");
    String rideID = "";

    if (Platform.isAndroid) {
      rideID = message["data"]['ride_id'];
      if (rideID != null) {
        print("Broken");
      } else {
        print('ride_id: $rideID');
      }
    }
    return rideID;
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Since the firebase_messaging get ^14.2.1 version I can't find an answer to how can I resolve the problem.

When I send a post from the Postman everything is fine, I get a notification on the blocked phone, but I have an error in the console:

W/FLTFireMsgService(13437): A background message could not be handled in Dart as no onBackgroundMessage handler has been registered.
W/FirebaseMessaging(13437): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.

**The Code is implemented **

import 'dart:io';
import 'package:cholachol_drive/globalvariables.dart';
import 'package:cholachol_drive/main.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

class PushNotificationService {
  FirebaseMessaging fcm = FirebaseMessaging.instance;

  Future initialize(context) async {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('Got a message whilst in the foreground!');
      print('Message data: ${message.data}');

      print('Message also contained a notification: ${message.notification}');
      // if (message.notification != null) {}
    });

//Background
    Future<void> _firebaseMessagingBackgroundHandler(
        RemoteMessage message) async {
      await Firebase.initializeApp();
      print("Handling a background message: ${message.messageId}");
    }
  }

  Future<String> getToken() async {
    String token = await FirebaseMessaging.instance.getToken();
    print("token: $token");

    DatabaseReference tokerRef = FirebaseDatabase.instance
        .ref()
        .child("drivers/${currentFirebaseUser.uid}/token");

    FirebaseMessaging.instance.subscribeToTopic('alldrivers');
    FirebaseMessaging.instance.subscribeToTopic('allusers');
  }

  String getRideID(Map<String, dynamic> message) {
    print("onLaunch: $message");
    String rideID = "";

    if (Platform.isAndroid) {
      rideID = message["data"]['ride_id'];
      if (rideID != null) {
        print("Broken");
      } else {
        print('ride_id: $rideID');
      }
    }
    return rideID;
  }
}


问:
GIT Behind/Ahead Counter as a way to track deployed features
I am working on a project, and we have many people working on it. We have 2 branches:

main

develop

When someone gets a task, they make a new branch for their task derived from develop and once they finish it it is approved via pull request to the develop branch using squash commit. This is important as feature might be worked on over few days and it can consist of many commits that we aren't particularly interested in. Once tested, the feature is approved to be transfered to the main branch.

We transfer the feature using cherry picking. This is why to us it is useful to have squash commit, because 1 feature becomes 1 commit that we cherry pick to main.

Suppose we have 5 new features on develop branch, all merged using squash commit.
When compared, behind counter is 0 and ahead counter is 5 compared to the main branch.
Perfectly logical. But if i want to cherry-pick 1 of those 5 commits from develop to the main i expected counter to show 0 for behind and 4 for ahead counter after it is done. This isn't the case unfortunately as cherry-picking makes new hash for the commit.

I expected i could use those counters to track features i have deployed to the main and it kind of bothers me that those counters stray away from each other by the day. How can i achieve what i expected?


问:
Adding Linkedin Sign In to Profile for App creation
I am wanting to see if a user could add their LinkedIn profile when signing up for my application instead of having to fill out all of their details. Is there an API integration that is currently able to do this?

No feedback from LinkedIn.


问:
Warmings with a dataframe before use xgb
I prepared a dataset before passing the data to the gb algorithm.

```<code>[1] "data.frame"
Warning messages:
1: In get(results[[i]], packages[[i]]) :
  restarting interrupted promise evaluation
2: In get(results[[i]], packages[[i]]) :
  internal error -3 in R_decompress1
3: In get(results[[i]], packages[[i]]) :
  restarting interrupted promise evaluation
4: In get(results[[i]], packages[[i]]) :
  internal error -3 in R_decompress1
</code>```

Then, I trained the model an got this issue.

```<code>Error in train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  lazy-load database '/home/user/R/x86_64-pc-linux-gnu-library/3.6/caret/R/caret.rdb' is corrupt
In addition: Warning messages:
1: In train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  restarting interrupted promise evaluation
2: In train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  internal error -3 in R_decompress1

</code>```

Body:
I prepared a dataset before passing the data to the gb algorithm.

[1] "data.frame"
Warning messages:
1: In get(results[[i]], packages[[i]]) :
  restarting interrupted promise evaluation
2: In get(results[[i]], packages[[i]]) :
  internal error -3 in R_decompress1
3: In get(results[[i]], packages[[i]]) :
  restarting interrupted promise evaluation
4: In get(results[[i]], packages[[i]]) :
  internal error -3 in R_decompress1

Then, I trained the model an got this issue.

Error in train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  lazy-load database '/home/user/R/x86_64-pc-linux-gnu-library/3.6/caret/R/caret.rdb' is corrupt
In addition: Warning messages:
1: In train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  restarting interrupted promise evaluation
2: In train(NL_Load_Actual ~ ., data = filter_train, method = "xgbLinear",  :
  internal error -3 in R_decompress1


问:
Socket.IO not working in regular browser mode (but works in incognito)
I have to connect to Socket.IO server from my app.
I'm using Angular wrapper ngx-socket-io without any special options set.
I have noticed that everything works when I'm connecting in incognito mode - in regular mode I get "cannot connect exception".

I was compering requests in Chrome Dev console and I haven't seen any difference between them.
Have anyone noticed similar issues ?


问:
Notify/check if the content of a custom gutenberg block has changed on save_post
I developed a custom gutenberg block that has some information saved in its attributes. I would like to know if there is a possibility to notify/check only if there is any change in the content of that block when updating the post. Is this possible?</p>


问:
How to view script output (specifically PowerShell) from a Jenkinsfile?
I'm pretty new to Jenkins, so not totally clear on how to assign/read variables.

I have a jenkinsfile with a couple stages and a bunch of steps. In one of the steps, I want to run a PowerShell script but it isn't accomplishing the intent. The problem is, when I'm in Jenkins and I go to the Console Output to troubleshoot why the PowerShell script isn't working, I don't see any of the output from the powershell script, I just see this:

```<code>[Pipeline] {
[Pipeline] powershell (Test PowerShell Script)
[Pipeline] }
</code>```

Here's a trimmed-down version of my code:

```<code>stages {
    stage('Stage 1') {
        agent { node {
            label "Windows"
            customWorkspace "D:\\Path"
        }}
        steps {
            dir('Directory') {
                withCredentials(
                    [usernameColonPassword(
                        credentialsId: 'credential1',
                        variable: 'BasicCred'
                    )]
                ) {
                    powershell(
                        label: 'Test PowerShell Script',
                        returnStdout: true,
                        script: 'echo Test'
                    )
                }
            }
        }
    }
}
</code>```

I tried using the code provided in this Jenkins article:

```<code>steps {
    dir('Directory') {
        withCredentials(
            [usernameColonPassword(
                credentialsId: 'credential1',
                variable: 'BasicCred'
            )]
        ) {
            def msg = powershell(
                label: 'Test PowerShell Script',
                returnStdout: true,
                script: 'echo Test'
            )
            println msg
        }
    }
}
</code>```

This threw an error:

```<code>WorkflowScript: 135: Expected a step @ line 135, column 25.
                         def msg = powershell(
                         ^
</code>```

I also tried putting it inside a node:

```<code>steps {
    dir('Directory') {
        node {
            withCredentials(
                [usernameColonPassword(
                    credentialsId: 'credential1',
                    variable: 'BasicCred'
                )]
            ) {
                def msg = powershell(
                    label: 'Test PowerShell Script',
                    returnStdout: true,
                    script: 'echo Test'
                )
                println msg
            }
        }
    }
}
</code>```

But it threw an error that the node is missing a label, and when I tried adding a label it threw another error.

So what's the right way to go about this? I just want to capture the output from the PowerShell script and see it so I can troubleshoot why it isn't working.

Body:
I'm pretty new to Jenkins, so not totally clear on how to assign/read variables.

I have a jenkinsfile with a couple stages and a bunch of steps. In one of the steps, I want to run a PowerShell script but it isn't accomplishing the intent. The problem is, when I'm in Jenkins and I go to the Console Output to troubleshoot why the PowerShell script isn't working, I don't see any of the output from the powershell script, I just see this:

[Pipeline] {
[Pipeline] powershell (Test PowerShell Script)
[Pipeline] }

Here's a trimmed-down version of my code:

stages {
    stage('Stage 1') {
        agent { node {
            label "Windows"
            customWorkspace "D:\\Path"
        }}
        steps {
            dir('Directory') {
                withCredentials(
                    [usernameColonPassword(
                        credentialsId: 'credential1',
                        variable: 'BasicCred'
                    )]
                ) {
                    powershell(
                        label: 'Test PowerShell Script',
                        returnStdout: true,
                        script: 'echo Test'
                    )
                }
            }
        }
    }
}

I tried using the code provided in this Jenkins article:

steps {
    dir('Directory') {
        withCredentials(
            [usernameColonPassword(
                credentialsId: 'credential1',
                variable: 'BasicCred'
            )]
        ) {
            def msg = powershell(
                label: 'Test PowerShell Script',
                returnStdout: true,
                script: 'echo Test'
            )
            println msg
        }
    }
}

This threw an error:

WorkflowScript: 135: Expected a step @ line 135, column 25.
                         def msg = powershell(
                         ^

I also tried putting it inside a node:

steps {
    dir('Directory') {
        node {
            withCredentials(
                [usernameColonPassword(
                    credentialsId: 'credential1',
                    variable: 'BasicCred'
                )]
            ) {
                def msg = powershell(
                    label: 'Test PowerShell Script',
                    returnStdout: true,
                    script: 'echo Test'
                )
                println msg
            }
        }
    }
}

But it threw an error that the node is missing a label, and when I tried adding a label it threw another error.

So what's the right way to go about this? I just want to capture the output from the PowerShell script and see it so I can troubleshoot why it isn't working.


问:
Which file contain the git alias (ohmybash)?
The gau tool and gf tool are installed, but I am unable to use them due to using ohmybash, which has a git alias set for gau and gf. I want to unalias it right now, but I'm not sure which file the git alias is in.

I checked

.bashrc

.profile

.zshrc

/etc/bashrc

/etc/profile


问:
Jasper Report: BarChart - ERROR Could not create chart customizer instance
I am trying to customize the space between bars my BarChart with a customizer class.
Following the documentation i created a customizer class

ChartCustomizer.java

```<code>package com.example.jasper;

import net.sf.jasperreports.engine.JRChart;
import net.sf.jasperreports.engine.JRAbstractChartCustomizer;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.*;

public class ChartCustomizer extends JRAbstractChartCustomizer {

    @Override
    public void customize(JFreeChart chart, JRChart jasperChart){

        CategoryPlot categoryPlot = chart.getCategoryPlot();
        BarRenderer br = (BarRenderer) categoryPlot.getRenderer();

        br.setItemMargin(2.0);
    }
}
</code>```

I extracted the .jar of this on intellij including the needed libs

jfreechart-1.5.4

jasperreports-5.6.1

jcommon-1.0.24

I included the .jar file to the JasperReport classpath

and i am using the full path name for the class

BUT still i get this error:

I am missing something?
Thanks for your help.

Body:
I am trying to customize the space between bars my BarChart with a customizer class.
Following the documentation i created a customizer class

ChartCustomizer.java

package com.example.jasper;

import net.sf.jasperreports.engine.JRChart;
import net.sf.jasperreports.engine.JRAbstractChartCustomizer;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.*;

public class ChartCustomizer extends JRAbstractChartCustomizer {

    @Override
    public void customize(JFreeChart chart, JRChart jasperChart){

        CategoryPlot categoryPlot = chart.getCategoryPlot();
        BarRenderer br = (BarRenderer) categoryPlot.getRenderer();

        br.setItemMargin(2.0);
    }
}

I extracted the .jar of this on intellij including the needed libs

jfreechart-1.5.4

jasperreports-5.6.1

jcommon-1.0.24

I included the .jar file to the JasperReport classpath

and i am using the full path name for the class

BUT still i get this error:

I am missing something?
Thanks for your help.


问:
Nginx returns 503 Unavailable when proxy_ssl_verify is activated
I'm testing proxying an HTTPS request from a server running Nginx (which I will call client-side) to another (server-side) that will proxy the request to a local Alertmanager. The server-side is TLS with a self-signed certificate. When I set proxy_ssl_verify to on on the client-side with the self-signed certificate in proxy_ssl_trusted_certificate, the client-side Nginx returns 503 Unavailable without logging any error.

Any help understanding why the client-side Nginx closes the connection silently and returns 503 would be much appreciated!

**Server-side Nginx config **

nginx.conf:

```<code>user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log      /var/log/nginx/access.log;
    sendfile        on;

    keepalive_timeout  65;

    include /etc/nginx/conf.d/sites-enabled/*.conf;
}
</code>```

alertmanager.conf:

```<code>upstream alertmanager {
  server        127.0.0.1:9193;
}

server {
  listen        127.0.0.1:9093 ssl;
  listen        192.168.128.2:9093 ssl;
  server_name   172.29.49.202;

  include             /etc/nginx/conf.d/common.conf;
  include             /etc/nginx/conf.d/ssl.conf;

  ssl_certificate /etc/ssl/private/alertmanager-cert.pem;
  ssl_certificate_key /etc/ssl/private/alertmanager-key.pem;

  location / {
    proxy_pass           http://alertmanager;
    include              /etc/nginx/conf.d/common_location.conf;
    auth_basic alertmanager;
    auth_basic_user_file /etc/nginx/conf.d/alertmanager/.htpasswd;
    add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header X-XSS-Protection "1; mode=block";
    if ($request_method = 'OPTIONS') {
      add_header 'Access-Control-Allow-Origin' $http_origin always;
      add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Credentials' 'true' always;
      add_header X-XSS-Protection "1; mode=block";
      return 200;
    }
  }
}
</code>```

ssl.conf:

```<code>ssl_protocols               TLSv1.2 TLSv1.3;
ssl_ciphers                 "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_prefer_server_ciphers   on;
ssl_dhparam                 /etc/ssl/private/dhparams.pem;
ssl_session_timeout         10m;
ssl_session_cache           shared:SSL:10m;
ssl_session_tickets         off;
</code>```

Nginx version on the server-side is 1.21.6.

Client-side Nginx config

nginx.conf:

```<code>user  nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 99999;

events {
    worker_connections  32768;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log   /var/log/nginx/access.log;

    sendfile        on;

    limit_req_zone $server_name zone=one:10m rate=1800r/s;

    keepalive_timeout  86400s;
    keepalive_requests 150000;
    client_header_timeout 86400s;
    client_max_body_size 50M;

    include /etc/nginx/conf.d/*.conf;
}
</code>```

default.conf:

```<code>upstream alertmanager {
server 172.29.49.202:9093;
}

server {
    listen       8080 ssl;
    listen       [::]:8080 ssl;
    server_name  management;

    ssl_certificate           /etc/ssl/nginx.crt;
    ssl_certificate_key       /etc/ssl/nginx.key;
    ssl_ciphers               "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-
RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       10m;

    location /alertmanager/ {
        limit_rate 1024k;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass_header Server;
        add_header X-XSS-Protection "1; mode=block";

        # Allow backend with keepalive connections
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Authorization "Basic <redacted>";

        proxy_pass https://alertmanager/;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem;

        proxy_next_upstream error timeout http_500;
    }
}
</code>```

Note that alertmanager-cert.pem on both servers are the same self-signed cert. The nginx version is 1.22.1.

Validating connection with the certificate

I can see that validating the upstream connection with the self-signed cert works fine.

```<code># curl -v  -H "Authorization: Basic <redacted>" https://172.29.49.202:9093 --cacert alertmanager-cert.pem

* Rebuilt URL to: https://172.29.49.202:9093/
*   Trying 172.29.49.202...
* TCP_NODELAY set
* Connected to 172.29.49.202 (172.29.49.202) port 9093 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=blabla
*  start date: Jan 11 23:46:27 2023 GMT
*  expire date: Jan 11 23:46:27 2024 GMT
*  subjectAltName: host "172.29.49.202" matched cert's IP address!
*  issuer: CN=blabla
*  SSL certificate verify ok.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET / HTTP/1.1
> Host: 172.29.49.202:9093
> User-Agent: curl/7.61.1
> Accept: */*
> Authorization: Basic <redacted>
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
...
</code>```

Running the command through Nginx with proxy_ssl_verify

When trying to do it through Nginx, I get a 503 response though.

```<code># curl -v -k https://127.0.0.1:8080/alertmanager/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: ...
*  start date: Jan 11 01:52:36 2023 GMT
*  expire date: Dec 18 01:52:36 2122 GMT
*  issuer: ...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 503 Service Temporarily Unavailable
< Server: nginx/1.22.1
< Date: Thu, 12 Jan 2023 19:18:50 GMT
< Content-Type: application/json
< Content-Length: 32
< Connection: keep-alive
< ETag: "63bf5851-20"
< Retry-After: 1
<
{"error":"Service Unavailable"}
</code>```

I tried capturing traffic on the server-side and I see that the TLS handshake gets done, but then the client-side Nginx closes the connection.

TLS handshake

I see this error in the client-side Nginx's logs, but nothing on the server-side.

```<code>[info] 17#17: *272 client closed connection while waiting for request, client: 172.29.49.112, server: 192.168.128.2:9093
</code>```

Testing without proxy_ssl_verify

When proxy_ssl_verify is disabled, the connection succeeds.

```<code># curl -v -k https://127.0.0.1:8080/alertmanager/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: ...
*  start date: Jan 11 01:52:36 2023 GMT
*  expire date: Dec 18 01:52:36 2122 GMT
*  issuer: ...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
< Date: Thu, 12 Jan 2023 19:33:21 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 1381
< Connection: keep-alive
< Server: nginx/1.21.6
< Accept-Ranges: bytes
< Cache-Control: no-cache, no-store, must-revalidate
< Expires: 0
< Last-Modified: Thu, 01 Jan 1970 00:00:01 GMT
< Pragma: no-cache
< Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin
< Access-Control-Allow-Methods: GET, POST, OPTIONS
< Access-Control-Allow-Credentials: true
< X-XSS-Protection: 1; mode=block
< X-XSS-Protection: 1; mode=block
</code>```

Body:
I'm testing proxying an HTTPS request from a server running Nginx (which I will call client-side) to another (server-side) that will proxy the request to a local Alertmanager. The server-side is TLS with a self-signed certificate. When I set proxy_ssl_verify to on on the client-side with the self-signed certificate in proxy_ssl_trusted_certificate, the client-side Nginx returns 503 Unavailable without logging any error.

Any help understanding why the client-side Nginx closes the connection silently and returns 503 would be much appreciated!

**Server-side Nginx config **

nginx.conf:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log      /var/log/nginx/access.log;
    sendfile        on;

    keepalive_timeout  65;

    include /etc/nginx/conf.d/sites-enabled/*.conf;
}

alertmanager.conf:

upstream alertmanager {
  server        127.0.0.1:9193;
}

server {
  listen        127.0.0.1:9093 ssl;
  listen        192.168.128.2:9093 ssl;
  server_name   172.29.49.202;

  include             /etc/nginx/conf.d/common.conf;
  include             /etc/nginx/conf.d/ssl.conf;

  ssl_certificate /etc/ssl/private/alertmanager-cert.pem;
  ssl_certificate_key /etc/ssl/private/alertmanager-key.pem;

  location / {
    proxy_pass           http://alertmanager;
    include              /etc/nginx/conf.d/common_location.conf;
    auth_basic alertmanager;
    auth_basic_user_file /etc/nginx/conf.d/alertmanager/.htpasswd;
    add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    add_header X-XSS-Protection "1; mode=block";
    if ($request_method = 'OPTIONS') {
      add_header 'Access-Control-Allow-Origin' $http_origin always;
      add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Content-Type, Origin' always;
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
      add_header 'Access-Control-Allow-Credentials' 'true' always;
      add_header X-XSS-Protection "1; mode=block";
      return 200;
    }
  }
}

ssl.conf:

ssl_protocols               TLSv1.2 TLSv1.3;
ssl_ciphers                 "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
ssl_prefer_server_ciphers   on;
ssl_dhparam                 /etc/ssl/private/dhparams.pem;
ssl_session_timeout         10m;
ssl_session_cache           shared:SSL:10m;
ssl_session_tickets         off;

Nginx version on the server-side is 1.21.6.

Client-side Nginx config

nginx.conf:

user  nginx;
worker_processes  4;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 99999;

events {
    worker_connections  32768;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log   /var/log/nginx/access.log;

    sendfile        on;

    limit_req_zone $server_name zone=one:10m rate=1800r/s;

    keepalive_timeout  86400s;
    keepalive_requests 150000;
    client_header_timeout 86400s;
    client_max_body_size 50M;

    include /etc/nginx/conf.d/*.conf;
}

default.conf:

upstream alertmanager {
server 172.29.49.202:9093;
}

server {
    listen       8080 ssl;
    listen       [::]:8080 ssl;
    server_name  management;

    ssl_certificate           /etc/ssl/nginx.crt;
    ssl_certificate_key       /etc/ssl/nginx.key;
    ssl_ciphers               "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-
RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       10m;

    location /alertmanager/ {
        limit_rate 1024k;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass_header Server;
        add_header X-XSS-Protection "1; mode=block";

        # Allow backend with keepalive connections
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Authorization "Basic <redacted>";

        proxy_pass https://alertmanager/;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem;

        proxy_next_upstream error timeout http_500;
    }
}

Note that alertmanager-cert.pem on both servers are the same self-signed cert. The nginx version is 1.22.1.

Validating connection with the certificate

I can see that validating the upstream connection with the self-signed cert works fine.

# curl -v  -H "Authorization: Basic <redacted>" https://172.29.49.202:9093 --cacert alertmanager-cert.pem

* Rebuilt URL to: https://172.29.49.202:9093/
*   Trying 172.29.49.202...
* TCP_NODELAY set
* Connected to 172.29.49.202 (172.29.49.202) port 9093 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/rbbn/ids/nginx/appsvc/alertmanager-cert.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=blabla
*  start date: Jan 11 23:46:27 2023 GMT
*  expire date: Jan 11 23:46:27 2024 GMT
*  subjectAltName: host "172.29.49.202" matched cert's IP address!
*  issuer: CN=blabla
*  SSL certificate verify ok.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET / HTTP/1.1
> Host: 172.29.49.202:9093
> User-Agent: curl/7.61.1
> Accept: */*
> Authorization: Basic <redacted>
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
...

Running the command through Nginx with proxy_ssl_verify

When trying to do it through Nginx, I get a 503 response though.

# curl -v -k https://127.0.0.1:8080/alertmanager/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: ...
*  start date: Jan 11 01:52:36 2023 GMT
*  expire date: Dec 18 01:52:36 2122 GMT
*  issuer: ...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 503 Service Temporarily Unavailable
< Server: nginx/1.22.1
< Date: Thu, 12 Jan 2023 19:18:50 GMT
< Content-Type: application/json
< Content-Length: 32
< Connection: keep-alive
< ETag: "63bf5851-20"
< Retry-After: 1
<
{"error":"Service Unavailable"}

I tried capturing traffic on the server-side and I see that the TLS handshake gets done, but then the client-side Nginx closes the connection.

TLS handshake

I see this error in the client-side Nginx's logs, but nothing on the server-side.

[info] 17#17: *272 client closed connection while waiting for request, client: 172.29.49.112, server: 192.168.128.2:9093

Testing without proxy_ssl_verify

When proxy_ssl_verify is disabled, the connection succeeds.

# curl -v -k https://127.0.0.1:8080/alertmanager/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: ...
*  start date: Jan 11 01:52:36 2023 GMT
*  expire date: Dec 18 01:52:36 2122 GMT
*  issuer: ...
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> GET /alertmanager/ HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/1.1 200 OK
< Date: Thu, 12 Jan 2023 19:33:21 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 1381
< Connection: keep-alive
< Server: nginx/1.21.6
< Accept-Ranges: bytes
< Cache-Control: no-cache, no-store, must-revalidate
< Expires: 0
< Last-Modified: Thu, 01 Jan 1970 00:00:01 GMT
< Pragma: no-cache
< Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin
< Access-Control-Allow-Methods: GET, POST, OPTIONS
< Access-Control-Allow-Credentials: true
< X-XSS-Protection: 1; mode=block
< X-XSS-Protection: 1; mode=block


问:
Synchronizing date and time across multiple Docker containers
I have a number of services inside of a Docker Compose right now, and I want to synchronize time between all of them. The catch being, I want to be able to "rewind time" in a sense, and have all the container's times synchronized and set to an arbitrary date and time in the past (exact time doesn't matter) so to each container, it is that date and time. It is important that all of the Docker containers are perfectly synchronized, since some of the functions used are based on the current date and time. As an example, containers A and B would both think it is 1/1/2020, even though it is not on the host system.

My first idea was to use an NTP container, and have each container connect to it to get the time. The issue is, I don't see a way to set the date and time in the past with NTP.

Another idea was to set the time manually for each container on startup, but this runs into the issue that each container won't be done spinning-up at the same time necessarily, leading to a time difference of a few seconds which breaks everything.

Does anyone have any ideas? Thanks in advance!


问:
grouping messages and processing bunch of messages at once with kafka
I have a Kafka cluster with multiple brokers. In my application, I need to group messages based on an Identifier(unique) and I need to put all the messages with the same ID into a separate location(topic or partition). My first question is how can we achieve this in Kafka. I am familiar with producing with a key in Kafka, but it just guarantees to put all the relative events in one place, But I need to make sure that the topic or partition only has messages with the same ID(nothing else inside that topic or partition).

My other question is how can we make the consumers subscribe to a specific topic, but run for example every 10 minutes (not as soon as one msg arrives) and process all the messages in that topic(or a specific partition)? By processing all the messages I mean literally on all the messages not one by one.


问:
How to add a slider filter for woocommerce WoodMart Theme
In an wordpress site, we have woodmart theme installed. In the sidebar I want to add a widget, which does something like this :

```<code>function myfunction($args) {

  add_slider($product_attribute, 'attribute_string');

}
</code>```

So for example, if there were EV -s being sold, then the slider could filter between two range values, and only EV-s that has a range within the slider interval will be shown.

I am not sure how to get started. I have found out, that this file has a function that creates the widgets wp-content/themes/woodmart/inc/widgets/class-widget-layered-nav.php. But I can't find where individual widgets are created.

My concrete question is, which file do i need to modify, to add a slider that can filter products by an attribute, and how do I find the appropriate attributes to be used in the function myfunction above.

I can't find any info in the woocommerce help forum, as support is limited, and they just say that edit the file ./wp-content/themes/woodmart/inc/integrations/elementor/elements/class-sidebar.php at my own risk - but that is not very helpful.

I see some woocommerce questions here, so I am looking for help. Thank you. I will accept with a php oran Ajax or jquery solution.

Body:
In an wordpress site, we have woodmart theme installed. In the sidebar I want to add a widget, which does something like this :

function myfunction($args) {

  add_slider($product_attribute, 'attribute_string');

}

So for example, if there were EV -s being sold, then the slider could filter between two range values, and only EV-s that has a range within the slider interval will be shown.

I am not sure how to get started. I have found out, that this file has a function that creates the widgets wp-content/themes/woodmart/inc/widgets/class-widget-layered-nav.php. But I can't find where individual widgets are created.

My concrete question is, which file do i need to modify, to add a slider that can filter products by an attribute, and how do I find the appropriate attributes to be used in the function myfunction above.

I can't find any info in the woocommerce help forum, as support is limited, and they just say that edit the file ./wp-content/themes/woodmart/inc/integrations/elementor/elements/class-sidebar.php at my own risk - but that is not very helpful.

I see some woocommerce questions here, so I am looking for help. Thank you. I will accept with a php oran Ajax or jquery solution.


问:
Quarkus reactive and JDBC datasource connection pooling
I'm using Quarkus and have a project with two default datasources connecting to the same database, one uses JDBC (Agroal) for a postgres copy operation, the other uses reactive (PgPool) for all other sql operations.

There's an option in quarkus QUARKUS_DATASOURCE_JDBC_POOLING_ENABLED that can be set to false to disable connection pooling for JDBC datasource. So my question is:

Does reactive and JDBC datasources share the same connection pool? If I disable the JDBC pooling, will it affect the reactive connection pool?

Is there a way to verify such behavior?

Thank you all.

Trying to figure out the behavior between reactive and JDBC datasource regarding connection pooling. Expecting that turning off the pooling for JDBC via the config QUARKUS_DATASOURCE_JDBC_POOLING_ENABLED will not impact reactive connection pool.


问:
Need help passing OpenWeatherMap data from app to widget
I have a weather app that uses the OpenWeatherMap API to collect its weather data. Everything works properly in the app, but I'm not sure exactly how to pass some of the information over to a widget.

Here is the weather data struct from the app:

```<code>struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
    let wind: Wind
    let visibility: Int
    let sys: Sys
    let timezone: Int
    let coord: Coord
}

struct Main: Codable {
    let temp: Double
    let pressure: Int
    let feels_like: Double
    let temp_min: Double
    let temp_max: Double
    let humidity: Int
}

struct Weather: Codable {
    let id: Int
}

struct Wind: Codable {
    let speed: Double
}

struct Sys: Codable {
    let sunrise: Double
    let sunset: Double
    let country: String
}

struct Coord: Codable {
    let lon: Double
    let lat: Double
}
</code>```

I understand that basics of widget timeline entries, but I'm not sure how it would work with a struct referencing another struct. Like I would want temperature, but that is within the Main struct instead of just WeatherData.

```<code>struct WeatherEntry: TimelineEntry {
    let date: Date
    let name: String
    let temperature: Main
}
</code>```

If I have the timeline entry set up like this, then all the instances of the entry in the timeline provider would want an init for every constant in Main, not just temp. I feel like I'm missing a step.

```<code>struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> WeatherEntry {
        WeatherEntry(date: Date(), name: "", temperature: Main(temp: <#T##Double#>, pressure: <#T##Int#>, feels_like: <#T##Double#>, temp_min: <#T##Double#>, temp_max: <#T##Double#>, humidity: <#T##Int#>))
    }
</code>```

Also a potentially separate issue, I have both celsius and fahrenheit temperatures that I would want to pass through from functions in a WeatherModel file from the JSON to see both at the same time. Would I be able to pass those through the same way?

```<code>struct WeatherModel {

    let conditionId: Int
    let cityName: String
    let temperature: Double
    let feels_like: Double
    let visibility: Int
    let humidity: Int
    let wind: Double
    let sunrise: Double
    let sunset: Double
    let timezone: Int
    let country: String
    let latitude: Double
    let longitude: Double

    var temperatureString: String {

        return String (format: "%.0f", temperature)
    }
}

struct WeatherModelFahrenheit {

    let conditionId: Int
    let cityName: String
    let temperatureFahrenheit: Double
    let feels_likeFahrenheit: Double
    let visibilityImperial: Int
    let windImperial: Double

    var temperatureStringFahrenheit: String {
        return String (format: "%.0f", temperatureFahrenheit)
    }
}
</code>```

If possible, I'd rather pass through the two temperature strings instead of the temperature from Main, but I feel like these are two completely different procedures. If I can accomplish that without having to rewrite any of the app code and just the widget code, that would be preferable, although I'm not sure if that would work that way. I've looked into App Groups for sharing information but I'm not sure if that would be better (or work) for what I'm trying to do.

Hopefully what I want to do is understandable from all that.

Body:
I have a weather app that uses the OpenWeatherMap API to collect its weather data. Everything works properly in the app, but I'm not sure exactly how to pass some of the information over to a widget.

Here is the weather data struct from the app:

struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
    let wind: Wind
    let visibility: Int
    let sys: Sys
    let timezone: Int
    let coord: Coord
}

struct Main: Codable {
    let temp: Double
    let pressure: Int
    let feels_like: Double
    let temp_min: Double
    let temp_max: Double
    let humidity: Int
}

struct Weather: Codable {
    let id: Int
}

struct Wind: Codable {
    let speed: Double
}

struct Sys: Codable {
    let sunrise: Double
    let sunset: Double
    let country: String
}

struct Coord: Codable {
    let lon: Double
    let lat: Double
}

I understand that basics of widget timeline entries, but I'm not sure how it would work with a struct referencing another struct. Like I would want temperature, but that is within the Main struct instead of just WeatherData.

struct WeatherEntry: TimelineEntry {
    let date: Date
    let name: String
    let temperature: Main
}

If I have the timeline entry set up like this, then all the instances of the entry in the timeline provider would want an init for every constant in Main, not just temp. I feel like I'm missing a step.

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> WeatherEntry {
        WeatherEntry(date: Date(), name: "", temperature: Main(temp: <#T##Double#>, pressure: <#T##Int#>, feels_like: <#T##Double#>, temp_min: <#T##Double#>, temp_max: <#T##Double#>, humidity: <#T##Int#>))
    }

Also a potentially separate issue, I have both celsius and fahrenheit temperatures that I would want to pass through from functions in a WeatherModel file from the JSON to see both at the same time. Would I be able to pass those through the same way?

struct WeatherModel {

    let conditionId: Int
    let cityName: String
    let temperature: Double
    let feels_like: Double
    let visibility: Int
    let humidity: Int
    let wind: Double
    let sunrise: Double
    let sunset: Double
    let timezone: Int
    let country: String
    let latitude: Double
    let longitude: Double

    var temperatureString: String {

        return String (format: "%.0f", temperature)
    }
}

struct WeatherModelFahrenheit {

    let conditionId: Int
    let cityName: String
    let temperatureFahrenheit: Double
    let feels_likeFahrenheit: Double
    let visibilityImperial: Int
    let windImperial: Double

    var temperatureStringFahrenheit: String {
        return String (format: "%.0f", temperatureFahrenheit)
    }
}

If possible, I'd rather pass through the two temperature strings instead of the temperature from Main, but I feel like these are two completely different procedures. If I can accomplish that without having to rewrite any of the app code and just the widget code, that would be preferable, although I'm not sure if that would work that way. I've looked into App Groups for sharing information but I'm not sure if that would be better (or work) for what I'm trying to do.

Hopefully what I want to do is understandable from all that.


问:
My github repository name automatically change from "mariadevicente" to this: https://mariadv19.github.io/mariadevicente/
I want to create a GitHub repository. I manage to do that, but despite the name that i put on "repository name" (in this case "mariade vicente"), when i go to settings and look at the URL it changes to this: https://mariadv19.github.io/mariadevicente/ . I don't understand what i'm doing wrong, i've tried with two differents repositories and had the same result.

I wanted to make a GitHub page with the URL mariadevicente , but i get this: https://mariadv19.github.io/mariadevicente/


问:
Extending User.IsInRole(string role)
I need to extend the User.IsInRole(string role) to account for a WebApplicationId.  I have created the following extension method:

```<code>public static class RoleHelper
{
    public static bool IsUserInRole(this User user, string role, int webApplicationId)
    {
        return true;
    }
}
</code>```

this User user references this class:

```<code>public class User : IdentityUser<long, Login, UserRole, Claim>
{
    public User() : base()
    {
        PreviousPasswords = new List<PreviousPassword>();
    }

    ......
}
</code>```

In my view when I call User.IsInRole("Administrator", 2) I receive the error No overload method 'IsInRole' takes 2 arguments  I added a reference in the Web.Config file in the View folder to where the extension method is stored, so I know that part is working.  Any assistance would be appreciated.

Title: Extending User.IsInRole(string role)

Body:
I need to extend the User.IsInRole(string role) to account for a WebApplicationId.  I have created the following extension method:

public static class RoleHelper
{
    public static bool IsUserInRole(this User user, string role, int webApplicationId)
    {
        return true;
    }
}

this User user references this class:

public class User : IdentityUser<long, Login, UserRole, Claim>
{
    public User() : base()
    {
        PreviousPasswords = new List<PreviousPassword>();
    }

    ......
}

In my view when I call User.IsInRole("Administrator", 2) I receive the error No overload method 'IsInRole' takes 2 arguments  I added a reference in the Web.Config file in the View folder to where the extension method is stored, so I know that part is working.  Any assistance would be appreciated.


问:
Laravel Livewire: AdminLte Input mask plugin date format(dd/mm/yyy) not working
I am using AdminLte Input mask plugin for masking inputs in backend. I am unable to use it with livewire after livewire has process data once.
Example: Multi Step Form.

Step 1 : Name

Step 2: Date of birth (here's where I need "dd/mm/yyyy" mask to be applied)

I tried multiple methods but form stops working once I enter step 2.

Input in blade of step 2

```<code><div class="form-floating has-validation">
    <input type="text" wire:model.lazy="dob" class="form-control"
           data-inputmask-alias="datetime" data-inputmask-inputformat="dd/mm/yyyy" data-mask=""
           inputmode="numeric" placeholder="dd/mm/yyyy">
    {!! Form::label('dob',trans('forms.dob'),array('for'=>'dob', 'class'=>' required')) !!}
</div>
</code>```

Some of the failed attempts are:

Attempt 1: adminlte.js

```<code>import 'admin-lte/plugins/inputmask/jquery.inputmask.min';
import 'admin-lte/plugins/chart.js/Chart.min';
import 'admin-lte/dist/js/adminlte.min';

$('[data-mask]').inputmask();
</code>```

and then calling the mixed file in app.blade.

Result: mask wasn't applied to input.

Attempt 2: push('after-script') or push('before-script') in blade file where livewire component has been called

```<code>@push('before-scripts')
    <script>
        $('[data-mask]').inputmask();
    </script>
@endpush
@push('after-scripts')
    <script>
        $('[data-mask]').inputmask();
    </script>
@endpush
</code>```

Both scripts were applied separately one at a time

Result: mask wasn't applied to input.

Attempt 3: inline-script

```<code><div class="form-floating has-validation">
    <input here...
</div>
<script>
    document.addEventListener('livewire:load', function () {
        $('[data-mask]').inputmask();
    })
</script>
</code>```

Result: mask wasn't applied to input.

Attempt 4: inline script(non livewire method)

```<code><div class="form-floating has-validation">
    <input here...
</div>
<script>
    $('[data-mask]').inputmask();
</script>
</code>```

Result: MASK WORKED But form stops working here at step 2

I am not sure where am I going wrong how can I make this work?

Body:
I am using AdminLte Input mask plugin for masking inputs in backend. I am unable to use it with livewire after livewire has process data once.
Example: Multi Step Form.

Step 1 : Name

Step 2: Date of birth (here's where I need "dd/mm/yyyy" mask to be applied)

I tried multiple methods but form stops working once I enter step 2.

Input in blade of step 2

    <input type="text" wire:model.lazy="dob" class="form-control"
           data-inputmask-alias="datetime" data-inputmask-inputformat="dd/mm/yyyy" data-mask=""
           inputmode="numeric" placeholder="dd/mm/yyyy">
    {!! Form::label('dob',trans('forms.dob'),array('for'=>'dob', 'class'=>' required')) !!}

Some of the failed attempts are:

Attempt 1: adminlte.js

import 'admin-lte/plugins/inputmask/jquery.inputmask.min';
import 'admin-lte/plugins/chart.js/Chart.min';
import 'admin-lte/dist/js/adminlte.min';

$('[data-mask]').inputmask();

and then calling the mixed file in app.blade.

Result: mask wasn't applied to input.

Attempt 2: push('after-script') or push('before-script') in blade file where livewire component has been called

@push('before-scripts')

@endpush
@push('after-scripts')

@endpush

Both scripts were applied separately one at a time

Result: mask wasn't applied to input.

Attempt 3: inline-script

    <input here...

Result: mask wasn't applied to input.

Attempt 4: inline script(non livewire method)

    <input here...

Result: MASK WORKED But form stops working here at step 2

I am not sure where am I going wrong how can I make this work?


问:
Excel - Search for specific words in string and extract text block up to specific character
I have data in a column of university credentials. I essentially need to search through credentials to find doctorate level or equivalent degrees and extract the text block including the degree and university up to a specific character. At this point I have a nicely working formula that is able to do this well for one input degree only.

```<code>=LEFT(RIGHT(A1,LEN(A1)-SEARCH("Ph.D",A1)+1),SEARCH(")",RIGHT(A1,LEN(A1)-SEARCH("Ph.D",A1)+1))-1)
</code>```

So, for example, if I want to find Ph.D. in a text string and extract that block up to the end of the university, it functions as follows:

RawUniverities
ParsedDoctoralLevel using formula

B.Sc. (Hons.)(Western Ontario), Ph.D.(British Columbia), LLM (Regina)
Ph.D.(British Columbia

B.A.(Simon Fraser), M.A.(Victoria), DPsych (British Columbia), MD (Oxford)

B.Sc.(Trent), M.Sc.(Alberta), D.Phil.(Western)

B.Sc.(Hons.) (Guelph),Ph.D (Queen's), MD(Toronto)
Ph.D (Queen's

The issue I'm having is I need to search for multiple different doctoral level degrees and then extract the block of text in the same manner with the degree and university. So, for this table example, the formula would need to search for Ph.D, MD, DPsych, and D.Phil, to capture everything. In instances where there are two degrees in the list, taking the leftmost would suffice.

An additional note, I have tried to solve this using the following formula, in theory it works but it spills over into the multiple columns, which just does not work for the parsing I'm doing.

```<code>=LEFT(RIGHT(A1,LEN(A1)-SEARCH({"Ph.D","MD","DPsych","D.Phil"},A1)+1),SEARCH(")",RIGHT(A1,LEN(A1)-SEARCH({"Ph.D","MD","DPsych","D.Phil"},A1)+1))-1)
</code>```

Wondering if anyone can help with a streamlined solution to this. I've hit the limits of my capabilities in excel with this and deep dives online have brought up very little.

It might be worth noting that the list of degrees that will need to be search could be upwards of 50 long. Not sure if the influences a best solution for this?

Edits: adding data to the table, having formatting issues.

Additional raw university test data if interested:

```<code>B.A.(Winnipeg Bible College), M.A.(London Bible College) M.A., Ph.D.(Toronto)
B.Com.(Hons.), Ph.D.(British Columbia)
B.Sc.(Birmingham), M.A.(Toronto), Ph.D.(London)
B.A. (Hons.)(Queen's), M.A.Sc. (Waterloo), Ph.D. (Queen's)
B.A. (York), M.A. (Western Ontario), Ph.D. (Rice)
BSc PT, (JUST), PT MSc (NYIT), Ph.D. (McGill)
M.F.A. (Concordia), M.A. (GCU Lahore)
Ph.D. (Queen's)
B.Sc. (Queen's), Ph.D.(Toronto)
B.A.(British Columbia), LL.B.(Queen's). LL.M.(California)
B.Sc., MD (Ottawa)
B.A., M.A. (Toronto), Ph.D. (Harvard)
LL.B.(Toronto), M.Sc., LL.M.(Queen's), D.Phil.(Oxford)
B.A.(McGill), J.D. (Queen's)
B.A. (Wilfrid Laurier), M.A. (Queen’s), M.A., Ph.D (Princeton)
M.Phil.(London), MN(Dalhousie), Ph.D.(Texas)
B.A. Hons (Wilfrid Laurier), M.A. (McMaster), Ph.D. (York)
B.Sc., M.Sc. (Isfahan), Ph.D. (Concordia)
B.A.(Keele) M.A., D.Phil.(Oxon)
L.S.M., B.A.(Toronto), J.D. (Queen's), LL.M.(Harvard)
B.A.(R.M.C.) M.A.(McGill) LL.B.(Queen's), LL.M.(London)
B.Sc., M.Sc., Ph.D. (Eӧtvӧs Loránd University, Budapest)
B.Sc., Ph.D. (British Columbia)
B.A., LL.B. (Toronto), S.J.D. (Harvard)
B.A.(Hons.)(Queen's), D.Phil.(Oxon)
B.Ac., MD (Argentina)
BA, MA, Ph.D. (Toronto)
</code>```

Body:
I have data in a column of university credentials. I essentially need to search through credentials to find doctorate level or equivalent degrees and extract the text block including the degree and university up to a specific character. At this point I have a nicely working formula that is able to do this well for one input degree only.

=LEFT(RIGHT(A1,LEN(A1)-SEARCH("Ph.D",A1)+1),SEARCH(")",RIGHT(A1,LEN(A1)-SEARCH("Ph.D",A1)+1))-1)

So, for example, if I want to find Ph.D. in a text string and extract that block up to the end of the university, it functions as follows:

RawUniverities
ParsedDoctoralLevel using formula

B.Sc. (Hons.)(Western Ontario), Ph.D.(British Columbia), LLM (Regina)
Ph.D.(British Columbia

B.A.(Simon Fraser), M.A.(Victoria), DPsych (British Columbia), MD (Oxford)

B.Sc.(Trent), M.Sc.(Alberta), D.Phil.(Western)

B.Sc.(Hons.) (Guelph),Ph.D (Queen's), MD(Toronto)
Ph.D (Queen's

The issue I'm having is I need to search for multiple different doctoral level degrees and then extract the block of text in the same manner with the degree and university. So, for this table example, the formula would need to search for Ph.D, MD, DPsych, and D.Phil, to capture everything. In instances where there are two degrees in the list, taking the leftmost would suffice.

An additional note, I have tried to solve this using the following formula, in theory it works but it spills over into the multiple columns, which just does not work for the parsing I'm doing.

=LEFT(RIGHT(A1,LEN(A1)-SEARCH({"Ph.D","MD","DPsych","D.Phil"},A1)+1),SEARCH(")",RIGHT(A1,LEN(A1)-SEARCH({"Ph.D","MD","DPsych","D.Phil"},A1)+1))-1)

Wondering if anyone can help with a streamlined solution to this. I've hit the limits of my capabilities in excel with this and deep dives online have brought up very little.

It might be worth noting that the list of degrees that will need to be search could be upwards of 50 long. Not sure if the influences a best solution for this?

Edits: adding data to the table, having formatting issues.

Additional raw university test data if interested:

B.A.(Winnipeg Bible College), M.A.(London Bible College) M.A., Ph.D.(Toronto)
B.Com.(Hons.), Ph.D.(British Columbia)
B.Sc.(Birmingham), M.A.(Toronto), Ph.D.(London)
B.A. (Hons.)(Queen's), M.A.Sc. (Waterloo), Ph.D. (Queen's)
B.A. (York), M.A. (Western Ontario), Ph.D. (Rice)
BSc PT, (JUST), PT MSc (NYIT), Ph.D. (McGill)
M.F.A. (Concordia), M.A. (GCU Lahore)
Ph.D. (Queen's)
B.Sc. (Queen's), Ph.D.(Toronto)
B.A.(British Columbia), LL.B.(Queen's). LL.M.(California)
B.Sc., MD (Ottawa)
B.A., M.A. (Toronto), Ph.D. (Harvard)
LL.B.(Toronto), M.Sc., LL.M.(Queen's), D.Phil.(Oxford)
B.A.(McGill), J.D. (Queen's)
B.A. (Wilfrid Laurier), M.A. (Queen’s), M.A., Ph.D (Princeton)
M.Phil.(London), MN(Dalhousie), Ph.D.(Texas)
B.A. Hons (Wilfrid Laurier), M.A. (McMaster), Ph.D. (York)
B.Sc., M.Sc. (Isfahan), Ph.D. (Concordia)
B.A.(Keele) M.A., D.Phil.(Oxon)
L.S.M., B.A.(Toronto), J.D. (Queen's), LL.M.(Harvard)
B.A.(R.M.C.) M.A.(McGill) LL.B.(Queen's), LL.M.(London)
B.Sc., M.Sc., Ph.D. (Eӧtvӧs Loránd University, Budapest)
B.Sc., Ph.D. (British Columbia)
B.A., LL.B. (Toronto), S.J.D. (Harvard)
B.A.(Hons.)(Queen's), D.Phil.(Oxon)
B.Ac., MD (Argentina)
BA, MA, Ph.D. (Toronto)


问:
Which azure storage class to use for application deployed in kubernetes
I am developing and spring boot application which will be deployed via kubernetes. I am currently using Azure file to storage my application logs.
But when my application scales the performance decreases. My observation is that this happened because of persistent volume in azure file.

Which is the best practice to store application logs in kubernetes