Fix non-appearing remote participant's video in Firefox after entering into call after long idle

Hello!
I experienced very nasty bug for long time:
Using Firefox open my website. Livekit exists in the webpack bundle, but it loads only when user enters into a video call.
Leave a tab opened for roughly 3 hours. (1 hour isn't enough). While waiting you can switch on other tab.
Then, after 3 hours, I start a video call from that tab(previously in "idle") and any other browser on any other device.
In Firefox it won't show the video from other participant, but audio will work (after turning on the microphone).
I don't know why this bug appears only after so long time. I tried to reduce the "appearance time" by "Unload" thru about:processes https://support.mozilla.org/en-US/kb/task-manager-tabs-or-extensions-are-slowing-firefox. but actually it didn't help me to "speedup" the appearance of the bug
One day I updated onto client-sdk-js v1.9.6 and noticed that this bug disappeared.
After some time I upgraded client-sdk-js again, onto v1.9.7 and bug appeared again.
I compared https://github.com/livekit/client-sdk-js/compare/v1.9.6...v1.9.7 versions and noticed change in getBrowser() function - seems in 1.9.6 the line
userAgent === undefined throws an error and it was fixed in 1.9.7.
I supposed that the error in getBrowser() function introduced in 1.9.6 broke some codepath and it eventually eliminated my bug.
I opened "Call hierarchy" in my IntelliJ IDEA, and found the most probably place of source of my bug.

I found this code ^.
I made an experiment - so, having assumption that error in isFireFox() function breaks that codepath and fixes my bug - I just removed isFireFox() call from this condition.
Then (after deploying it on server) I left my Firefox tab again for more 3 hours idle, and the bug disappeared. I checked it twice, and it works in both attempts.
So, if you want to validate my patch - you can
a) npm install<EMAIL_ADDRESS>- the bug presents
b) npm install<EMAIL_ADDRESS>- the bug doesn't present
c) npm install git://github.com/nkonev/client-sdk-js#fix-non-appearing-video-after-a-long-idle_release - it is my patched version, the bug doesn't present
I have no any piece of information why this code was added for Firefox, but I didn't notice any problems with my patched client-sdk-js version (where isFireFox() was removed from the condition). I think today we don't need it for the modern Firefox versions (I use 112.0.1, but the bug existed somewhere from the last summer, when I migrated from ion-sfu and ion-sdk-js onto livekit stack)

@davidzhao seems it was added in your commit 7722339a9ea0053e2f77d42c047a1619e06c3c0d https://github.com/livekit/client-sdk-js/pull/142
cc @lukasIO @boks1971

hi @nkonev, thanks for the PR.
trying to understand the underlying issue better.
If you have a reproducible setup for this, could you check whether the issue is that the function within the timeout does not get executed at all or if it's being delayed or whatever...
Intervals and timeouts tend to get throttled a lot in idle modes, so wondering if it executes eventually or if the execution is being missed entirely.

@lukasIO
Just branched from c49b7591, added some console.log:
...
  console.log("before avoiding flicker code")
  // avoid flicker
  if (element.srcObject !== mediaStream) {
    console.log("avoiding flicker code - first condition passed : element.srcObject !== mediaStream")
    element.srcObject = mediaStream;
    if ((isSafari() || isFireFox()) && element instanceof HTMLVideoElement) {
      console.log("avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement")
      // Firefox also has a timing issue where video doesn't actually get attached unless
      // performed out-of-band
      // Safari 15 has a bug where in certain layouts, video element renders
      // black until the page is resized or other changes take place.
      // Resetting the src triggers it to render.
      // https://developer.apple.com/forums/thread/690523
      setTimeout(() => {
        console.log("avoiding flicker code - inside setTimeout()")
        element.srcObject = mediaStream;
        // Safari 15 sometimes fails to start a video
        // when the window is backgrounded before the first frame is drawn
        // manually calling play here seems to fix that
        element.play().catch(() => {
          /* do nothing */
        });
      }, 0);
    }
  }
  console.log("after avoiding flicker code")
}

https://github.com/nkonev/client-sdk-js/commit/b67731e65035993254abf43ec846b8b6b5aed457
Here is output (no bug because of no idle)

Click me
Firefox user connencts
13:11:50.638 Server overrided videoResolution to h720 main_1686647089282.js:2:93794
13:11:50.638 Server overrided screenResolution to h1080 main_1686647089282.js:2:93979
13:11:50.638 Server overrided videoSimulcast to true main_1686647089282.js:2:94158
13:11:50.639 Server overrided screenSimulcast to false main_1686647089282.js:2:94337
13:11:50.639 Server overrided roomDynacast to true main_1686647089282.js:2:94506
13:11:50.639 Server overrided roomAdaptiveStream to true main_1686647089282.js:2:94693
13:11:50.639 Creating room with dynacast true adaptiveStream true 887_1686647089282.js:2:390260
13:11:50.640 Injecting xsrf token to header 17a295fb-c07b-46a3-a708-d3aff430177d main_1686647089282.js:2:681850
13:11:50.645
XHRGET
https://chat.nkonev.name/api/video/232/token
[HTTP/2 200 OK 180ms]
13:11:50.831 Got video token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODY2NTExMTAsImlzcyI6IkFQSXpuSnhXU2hHVzNLdCIsIm1ldGFkYXRhIjoie1widXNlcklkXCI6MSxcImxvZ2luXCI6XCJhZG1pblwiLFwiYXZhdGFyXCI6XCIvYXBpL3N0b3JhZ2UvcHVibGljL3VzZXIvYXZhdGFyLzFfQVZBVEFSXzIwMHgyMDAuanBnP3RpbWU9MTY3NjkzMDY1N1wifSIsIm5iZiI6MTY4NjY0NzUxMCwic3ViIjoiMV8wNDE4MGNkMC03OGFhLTQ1MmMtOGExOC1lOGQ2YmZlYWJjZTIiLCJ2aWRlbyI6eyJjYW5QdWJsaXNoIjp0cnVlLCJjYW5TdWJzY3JpYmUiOnRydWUsInJvb20iOiJjaGF0MjMyIiwicm9vbUpvaW4iOnRydWV9fQ.hM-8eRIe5ysh5T-4Fz55Hkc4J7jgE6ydug1CFzSso6I 887_1686647089282.js:2:391820
13:11:51.187 Creating media tracks audioId null videoid null videoResolution
Object { width: 1280, height: 720, frameRate: 30, aspectRatio: 1.7777777777777777 }
screenResolution
Object { width: 1920, height: 1080, frameRate: 30, aspectRatio: 1.7777777777777777 }
videoSimulcast true screenSimulcast false 887_1686647089282.js:2:393329
13:11:51.437 isMobileFirefox =  false  in case Mobile Firefox simulcast for video tracks will be disabled 887_1686647089282.js:2:395205
13:11:51.438 Publishing local audio screen=false track with name track_audio__screen_false_f461103d-1fbf-4b87-bfa7-d3cbbf940f04 and simulcast true 887_1686647089282.js:2:395446
13:11:51.539 LocalTrackPublished to room.name chat232 887_1686647089282.js:2:390977
13:11:51.539 LocalTrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1686647089282.js:2:391040
13:11:51.542 Processing audio track
Object { _events: {…}, _eventsCount: 2, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "audio", trackSid: "TR_AMPkWpDdtXvCw4", trackName: "track_audio__screen_false_f461103d-1fbf-4b87-bfa7-d3cbbf940f04", source: "microphone", … }
887_1686647089282.js:2:387598
13:11:51.543 candidatesWithoutAudio
Array []
candidateToAppendAudio null 887_1686647089282.js:2:387745
13:11:51.554 Setting source audio for videoRef=
  track=
Object { _events: {…}, _eventsCount: 2, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "audio", trackSid: "TR_AMPkWpDdtXvCw4", trackName: "track_audio__screen_false_f461103d-1fbf-4b87-bfa7-d3cbbf940f04", source: "microphone", … }
audio tag id= local-b1b9973e-625a-4a57-802d-6680604753fe , enabled= true 887_1686647089282.js:2:383082
13:11:51.555 Audio track was set TR_AMPkWpDdtXvCw4 to local-b1b9973e-625a-4a57-802d-6680604753fe 887_1686647089282.js:2:387964
13:11:51.596 Published track sid= TR_AMPkWpDdtXvCw4  kind= audio 887_1686647089282.js:2:395657
13:11:51.596 Publishing local video screen=false track with name track_video__screen_false_63412d1b-97b1-4138-b496-497cbdb4376d and simulcast true 887_1686647089282.js:2:395446
13:11:51.724 LocalTrackPublished to room.name chat232 887_1686647089282.js:2:390977
13:11:51.725 LocalTrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1686647089282.js:2:391040
13:11:51.731 Processing audio track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1686647089282.js:2:387598
13:11:51.732 Skipping audio
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1686647089282.js:2:387677
13:11:51.733 Processing video track
Object { _events: {…}, _eventsCount: 2, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "video", trackSid: "TR_VCkmFpVZWiTgrL", trackName: "track_video__screen_false_63412d1b-97b1-4138-b496-497cbdb4376d", source: "camera", … }
887_1686647089282.js:2:387076
13:11:51.734 candidatesWithoutVideo
Array [ {…} ]
candidateToAppendVideo
Object { _uid: 1683, _isVue: true, __v_skip: true, _scope: {…}, "$options": {…}, _renderProxy: {…}, _self: {…}, "$parent": undefined, "$root": {…}, "$children": (4) […], … }
887_1686647089282.js:2:387223
13:11:51.734 Setting source video for videoRef=
  track=
Object { _events: {…}, _eventsCount: 2, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "video", trackSid: "TR_VCkmFpVZWiTgrL", trackName: "track_video__screen_false_63412d1b-97b1-4138-b496-497cbdb4376d", source: "camera", … }
video tag id= local-b1b9973e-625a-4a57-802d-6680604753fe , enabled= true 887_1686647089282.js:2:383349
13:11:51.735 before avoiding flicker code 887_1686647089282.js:2:265047
13:11:51.736 avoiding flicker code - first condition passed : element.srcObject !== mediaStream 887_1686647089282.js:2:265109
13:11:51.736 avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement 887_1686647089282.js:2:265267
13:11:51.736 after avoiding flicker code 887_1686647089282.js:2:265505
13:11:51.736 Video track was set TR_VCkmFpVZWiTgrL to local-b1b9973e-625a-4a57-802d-6680604753fe 887_1686647089282.js:2:387442
13:11:51.741 Published track sid= TR_VCkmFpVZWiTgrL  kind= video 887_1686647089282.js:2:395657
13:11:51.744 avoiding flicker code - inside setTimeout() 887_1686647089282.js:2:265400
13:11:51.994 Got globalEvents event
Object { data: {…} }
main_1686647089282.js:2:40392
13:11:52.315 connected to room chat232 887_1686647089282.js:2:392095
13:11:52.887 Got globalEvents event
Object { data: {…} }
main_1686647089282.js:2:40392
Second user (Mobile Chrome) connects
13:13:20.030 TrackPublished to room.name chat232 887_1686647089282.js:2:390495
13:13:20.030 TrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1686647089282.js:2:390553
13:13:20.031 Processing video track
Object { _events: {…}, _eventsCount: 9, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "video", trackSid: "TR_VCNLrGDQmJg96w", trackName: "track_video__screen_false_40eda102-2ed4-470c-86d7-b0f4b6c9a0b0", source: "camera", … }
887_1686647089282.js:2:387076
13:13:20.032 candidatesWithoutVideo
Array [ {…} ]
candidateToAppendVideo
Object { _uid: 1696, _isVue: true, __v_skip: true, _scope: {…}, "$options": {…}, _renderProxy: {…}, _self: {…}, "$parent": undefined, "$root": {…}, "$children": (2) […], … }
887_1686647089282.js:2:387223
13:13:20.033 Setting source video for videoRef=
  track=
Object { _events: {…}, _eventsCount: 9, _maxListeners: 100, metadataMuted: false, handleMuted: handleMuted(), handleUnmuted: handleUnmuted()
, kind: "video", trackSid: "TR_VCNLrGDQmJg96w", trackName: "track_video__screen_false_40eda102-2ed4-470c-86d7-b0f4b6c9a0b0", source: "camera", … }
video tag id= remote-c82d76aa-6d81-46b4-b0eb-ce4eb224ce4e , enabled= true 887_1686647089282.js:2:383349
13:13:20.034 When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start 887_1686647089282.js:2:311715
13:13:20.034 before avoiding flicker code 887_1686647089282.js:2:265047
13:13:20.035 after avoiding flicker code 887_1686647089282.js:2:265505
13:13:20.050 Video track was set TR_VCNLrGDQmJg96w to remote-c82d76aa-6d81-46b4-b0eb-ce4eb224ce4e 887_1686647089282.js:2:387442
13:13:20.060 avoiding flicker code - inside setTimeout() 887_1686647089282.js:2:265400
13:13:20.060 could not playback audio DOMException: The fetching process for the media resource was aborted by the user agent at the user's request. 887_1686647089282.js:2:263316
13:13:20.061 could not playback audio DOMException: The fetching process for the media resource was aborted by the user agent at the user's request. 887_1686647089282.js:2:263316
13:13:20.299 before avoiding flicker code 887_1686647089282.js:2:265047
13:13:20.300 after avoiding flicker code 887_1686647089282.js:2:265505
13:13:20.301 Got globalEvents event
Object { data: {…} }
main_1686647089282.js:2:40392
13:13:20.328 Got globalEvents event
Object { data: {…} }
main_1686647089282.js:2:40392
13:13:20.352 before avoiding flicker code 887_1686647089282.js:2:265047
13:13:20.352 after avoiding flicker code 887_1686647089282.js:2:265505
13:13:22.327 Got globalEvents event
Object { data: {…} }
main_1686647089282.js:2:40392

Let me wait for 3+ hours to grab logs when bug occurs

@lukasIO  It turned out harder to reproduce than I expected.
Below is log from the unpatched version 1.10.0

Click me

When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start 173_1686685544210.js:1:326030
Video track was set TR_VCK7eYRF8w3LGx to remote-fbce1aef-5ced-469b-baea-20cc66789eda 746_1686685544210.js:1:12390
connected to room chat232 746_1686685544210.js:1:17064
could not playback audio DOMException: The fetching process for the media resource was aborted by the user agent at the user's request.
    eo https://chat.nkonev.name/173_1686685544210.js:1
    setTimeout handler*eo https://chat.nkonev.name/173_1686685544210.js:1
    attach https://chat.nkonev.name/173_1686685544210.js:1
    attach https://chat.nkonev.name/173_1686685544210.js:1
    setAudioStream https://chat.nkonev.name/746_1686685544210.js:1
    drawNewComponentOrInsertIntoExisting https://chat.nkonev.name/746_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    getOrCreateParticipant https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    addTrackPublication https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    setTrack https://chat.nkonev.name/173_1686685544210.js:1
    addSubscribedMediaTrack https://chat.nkonev.name/173_1686685544210.js:1
    onTrackAdded https://chat.nkonev.name/173_1686685544210.js:1
    n https://chat.nkonev.name/173_1686685544210.js:1
    di https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    attemptConnection https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    attemptConnection https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    promise https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    promise https://chat.nkonev.name/173_1686685544210.js:1
    as https://chat.nkonev.name/173_1686685544210.js:1
    connect https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    connect https://chat.nkonev.name/173_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    t https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    mounted https://chat.nkonev.name/746_1686685544210.js:1
    Ce https://chat.nkonev.name/main_1686685544210.js:2
    Qe https://chat.nkonev.name/main_1686685544210.js:2
    insert https://chat.nkonev.name/main_1686685544210.js:2
    $ https://chat.nkonev.name/main_1686685544210.js:2
    Or https://chat.nkonev.name/main_1686685544210.js:2
    _update https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    get https://chat.nkonev.name/main_1686685544210.js:2
    run https://chat.nkonev.name/main_1686685544210.js:2
    ui https://chat.nkonev.name/main_1686685544210.js:2
    Le https://chat.nkonev.name/main_1686685544210.js:2
    Oe https://chat.nkonev.name/main_1686685544210.js:2
    promise callback*Ie https://chat.nkonev.name/main_1686685544210.js:2
    Le https://chat.nkonev.name/main_1686685544210.js:2
    update https://chat.nkonev.name/main_1686685544210.js:2
    update https://chat.nkonev.name/main_1686685544210.js:2
    notify https://chat.nkonev.name/main_1686685544210.js:2
    set https://chat.nkonev.name/main_1686685544210.js:2
    init https://chat.nkonev.name/main_1686685544210.js:2
    init https://chat.nkonev.name/main_1686685544210.js:2
    updateRoute https://chat.nkonev.name/main_1686685544210.js:2
    transitionTo https://chat.nkonev.name/main_1686685544210.js:2
    confirmTransition https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    Sn https://chat.nkonev.name/main_1686685544210.js:2
    confirmTransition https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
173_1686685544210.js:1:277785
could not playback audio DOMException: The fetching process for the media resource was aborted by the user agent at the user's request.
    eo https://chat.nkonev.name/173_1686685544210.js:1
    setTimeout handler*eo https://chat.nkonev.name/173_1686685544210.js:1
    attach https://chat.nkonev.name/173_1686685544210.js:1
    attach https://chat.nkonev.name/173_1686685544210.js:1
    setAudioStream https://chat.nkonev.name/746_1686685544210.js:1
    drawNewComponentOrInsertIntoExisting https://chat.nkonev.name/746_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    getOrCreateParticipant https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    addTrackPublication https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    setTrack https://chat.nkonev.name/173_1686685544210.js:1
    addSubscribedMediaTrack https://chat.nkonev.name/173_1686685544210.js:1
    onTrackAdded https://chat.nkonev.name/173_1686685544210.js:1
    n https://chat.nkonev.name/173_1686685544210.js:1
    di https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    emit https://chat.nkonev.name/173_1686685544210.js:1
    attemptConnection https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    attemptConnection https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    promise https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    promise https://chat.nkonev.name/173_1686685544210.js:1
    as https://chat.nkonev.name/173_1686685544210.js:1
    connect https://chat.nkonev.name/173_1686685544210.js:1
    o https://chat.nkonev.name/173_1686685544210.js:1
    promise callback*c https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    Kt https://chat.nkonev.name/173_1686685544210.js:1
    connect https://chat.nkonev.name/173_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    t https://chat.nkonev.name/173_1686685544210.js:1
    s https://chat.nkonev.name/173_1686685544210.js:1
    startRoom https://chat.nkonev.name/746_1686685544210.js:1
    mounted https://chat.nkonev.name/746_1686685544210.js:1
    Ce https://chat.nkonev.name/main_1686685544210.js:2
    Qe https://chat.nkonev.name/main_1686685544210.js:2
    insert https://chat.nkonev.name/main_1686685544210.js:2
    $ https://chat.nkonev.name/main_1686685544210.js:2
    Or https://chat.nkonev.name/main_1686685544210.js:2
    _update https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    get https://chat.nkonev.name/main_1686685544210.js:2
    run https://chat.nkonev.name/main_1686685544210.js:2
    ui https://chat.nkonev.name/main_1686685544210.js:2
    Le https://chat.nkonev.name/main_1686685544210.js:2
    Oe https://chat.nkonev.name/main_1686685544210.js:2
    promise callback*Ie https://chat.nkonev.name/main_1686685544210.js:2
    Le https://chat.nkonev.name/main_1686685544210.js:2
    update https://chat.nkonev.name/main_1686685544210.js:2
    update https://chat.nkonev.name/main_1686685544210.js:2
    notify https://chat.nkonev.name/main_1686685544210.js:2
    set https://chat.nkonev.name/main_1686685544210.js:2
    init https://chat.nkonev.name/main_1686685544210.js:2
    init https://chat.nkonev.name/main_1686685544210.js:2
    updateRoute https://chat.nkonev.name/main_1686685544210.js:2
    transitionTo https://chat.nkonev.name/main_1686685544210.js:2
    confirmTransition https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
    Sn https://chat.nkonev.name/main_1686685544210.js:2
    confirmTransition https://chat.nkonev.name/main_1686685544210.js:2
    n https://chat.nkonev.name/main_1686685544210.js:2
173_1686685544210.js:1:277785
Got globalEvents event
Object { data: {…} }
main_1686685544210.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1686685544210.js:2:40392

I see When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
may be it is the reason of bug
Why there this message appears ?
my codepath candidateToAppendVideo.setVideoStream(track, cameraEnabled) -> setVideoStream includes cameraPub?.videoTrack?.attach(this.$refs.videoRef);
Can you point me where I'm wrong ?

@lukasIO  Here is log of livekit-js with additional console.log when the issue appeared

Click me - filtered by "avoiding flicker"
before avoiding flicker code 887_1687230919391.js:2:265047
avoiding flicker code - first condition passed : element.srcObject !== mediaStream, assigning element.srcObject =
MediaStream { id: "{a8ee1e7b-9f60-408f-9abc-bf4019332051}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265109
avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement 887_1687230919391.js:2:265300
after avoiding flicker code 887_1687230919391.js:2:265623
avoiding flicker code - inside setTimeout(), assigning element.srcObject =
MediaStream { id: "{a8ee1e7b-9f60-408f-9abc-bf4019332051}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265433
before avoiding flicker code 887_1687230919391.js:2:265047
avoiding flicker code - first condition passed : element.srcObject !== mediaStream, assigning element.srcObject =
MediaStream { id: "{564a2f8a-7042-454e-ba97-75c8c62ab2aa}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265109
avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement 887_1687230919391.js:2:265300
after avoiding flicker code 887_1687230919391.js:2:265623
before avoiding flicker code 887_1687230919391.js:2:265047
after avoiding flicker code 887_1687230919391.js:2:265623
avoiding flicker code - inside setTimeout(), assigning element.srcObject =
MediaStream { id: "{564a2f8a-7042-454e-ba97-75c8c62ab2aa}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265433
<!-- some time I watched logs -->
avoiding flicker code - err in play DOMException: The fetching process for the media resource was aborted by the user agent at the user's request. <-- when I exit from call

Click me - full
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 2 main_1687230919391.js:2:681850
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
gotQuery undefined main_1687230919391.js:2:57679
doSearch in App <empty string> main_1687230919391.js:2:635608
this.searchString <empty string> main_1687230919391.js:2:57731
Unsubscribing from chatEvents main_1687230919391.js:2:41062
Got compete in chatEvents subscription main_1687230919391.js:2:40894
infiniteHandler "" main_1687230919391.js:2:675437
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 main_1687230919391.js:2:681850
Unsubscribing from userOnlineTetATetInChatList main_1687230919391.js:2:41062
Resetting infinite loader<PHONE_NUMBER>753 887_1687230919391.js:2:411413
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Watched on newRoute in MessageList
Object { name: "chat", meta: {}, path: "/chat/232", hash: "", query: {}, params: {…}, fullPath: "/chat/232", matched: (1) […] }
  oldRoute undefined 887_1687230919391.js:2:413467
gotQuery undefined main_1687230919391.js:2:57679
doSearch in App <empty string> main_1687230919391.js:2:635608
this.searchString <empty string> main_1687230919391.js:2:57731
Unsubscribing from userOnlineTetATetInChatList main_1687230919391.js:2:41062
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 main_1687230919391.js:2:681850
Got info about chat in ChatView, chatId= 232
Object { id: Getter & Setter, name: Getter & Setter, avatar: Getter & Setter, avatarBig: Getter & Setter, shortInfo: Getter & Setter, lastUpdateDateTime: Getter & Setter, participantIds: Getter & Setter, canEdit: Getter & Setter, canDelete: Getter & Setter, canLeave: Getter & Setter, … }
887_1687230919391.js:2:418427
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 2 main_1687230919391.js:2:681850
Unsubscribing from chatEvents main_1687230919391.js:2:41062
Subscribing to chatEvents main_1687230919391.js:2:40270
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 2 main_1687230919391.js:2:681850
Resetting infinite loader<PHONE_NUMBER>329 main_1687230919391.js:2:674405
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
createCall main_1687230919391.js:2:633796
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 main_1687230919391.js:2:681850
Watched on newRoute in MessageList
Object { name: "videochat", meta: {}, path: "/chat/232/video", hash: "", query: {}, params: {…}, fullPath: "/chat/232/video", matched: (1) […] }
  oldRoute
Object { name: "chat", meta: {}, path: "/chat/232", hash: "", query: {}, params: {…}, fullPath: "/chat/232", matched: (1) […] }
887_1687230919391.js:2:413467
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 main_1687230919391.js:2:681850
On panel add
Array [ {…} ]
887_1687230919391.js:2:416608
Restoring from
Object { video: 41.53846153846154, messages: 22.2169969768223, edit: 36.24454148471616 }
887_1687230919391.js:2:417373
Server overrided videoResolution to h720 main_1687230919391.js:2:93794
Server overrided screenResolution to h1080 main_1687230919391.js:2:93979
Server overrided videoSimulcast to true main_1687230919391.js:2:94158
Server overrided screenSimulcast to false main_1687230919391.js:2:94337
Server overrided roomDynacast to true main_1687230919391.js:2:94506
Server overrided roomAdaptiveStream to true main_1687230919391.js:2:94693
Creating room with dynacast true adaptiveStream true 887_1687230919391.js:2:390378
Injecting xsrf token to header 5f76a197-6b96-4199-ae92-46b86a037e31 main_1687230919391.js:2:681850
Got video token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODcyNzM1NzAsImlzcyI6IkFQSXpuSnhXU2hHVzNLdCIsIm1ldGFkYXRhIjoie1widXNlcklkXCI6MSxcImxvZ2luXCI6XCJhZG1pblwiLFwiYXZhdGFyXCI6XCIvYXBpL3N0b3JhZ2UvcHVibGljL3VzZXIvYXZhdGFyLzFfQVZBVEFSXzIwMHgyMDAuanBnP3RpbWU9MTY3NjkzMDY1N1wifSIsIm5iZiI6MTY4NzI2OTk3MCwic3ViIjoiMV83N2UzZjAyYi1kZmQ5LTRiY2QtOThmMS01Y2RhNTJmYjUxYzkiLCJ2aWRlbyI6eyJjYW5QdWJsaXNoIjp0cnVlLCJjYW5TdWJzY3JpYmUiOnRydWUsInJvb20iOiJjaGF0MjMyIiwicm9vbUpvaW4iOnRydWV9fQ.kM-XJcX80YwSreXaNFbon3pRIeFRdvco-iA3rkqBqAc 887_1687230919391.js:2:391938
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Creating media tracks audioId null videoid null videoResolution
Object { width: 1280, height: 720, frameRate: 30, aspectRatio: 1.7777777777777777 }
 screenResolution
Object { width: 1920, height: 1080, frameRate: 30, aspectRatio: 1.7777777777777777 }
 videoSimulcast true screenSimulcast false 887_1687230919391.js:2:393447
TrackPublished to room.name chat232 887_1687230919391.js:2:390613
TrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1687230919391.js:2:390671
Processing video track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
candidatesWithoutVideo
Array []
 candidateToAppendVideo null 887_1687230919391.js:2:387341
Setting source video for videoRef=
<video id="remote-6b809c79-896f-47c5-bb6b-031f783e2a44" class="video-element video-element-top" data-v-6a74c99a="" autoplay="" playsinline="">  track=
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
  video tag id= remote-6b809c79-896f-47c5-bb6b-031f783e2a44 , enabled= true 887_1687230919391.js:2:383467
When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start 887_1687230919391.js:2:311833
before avoiding flicker code 887_1687230919391.js:2:265047
avoiding flicker code - first condition passed : element.srcObject !== mediaStream, assigning element.srcObject =
MediaStream { id: "{6782f628-f118-4596-ae13-e935cc0828e9}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265109
avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement 887_1687230919391.js:2:265300
after avoiding flicker code 887_1687230919391.js:2:265623
Video track was set TR_VC9XR6n6ojXj6R to remote-6b809c79-896f-47c5-bb6b-031f783e2a44 887_1687230919391.js:2:387560
TrackPublished to room.name chat232 887_1687230919391.js:2:390613
TrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1687230919391.js:2:390671
Processing audio track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1687230919391.js:2:387716
candidatesWithoutAudio
Array [ {…} ]
 candidateToAppendAudio
Object { _uid: 2448, _isVue: true, __v_skip: true, _scope: {…}, "$options": {…}, _renderProxy: {…}, _self: {…}, "$parent": undefined, "$root": {…}, "$children": (2) […], … }
887_1687230919391.js:2:387863
Setting source audio for videoRef=
<video id="remote-6b809c79-896f-47c5-bb6b-031f783e2a44" class="video-element video-element-top" data-v-6a74c99a="" autoplay="" playsinline="">  track=
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
  audio tag id= remote-6b809c79-896f-47c5-bb6b-031f783e2a44 , enabled= false 887_1687230919391.js:2:383200
before avoiding flicker code 887_1687230919391.js:2:265047
after avoiding flicker code 887_1687230919391.js:2:265623
Audio track was set TR_AM66cffUbd8TUR to remote-6b809c79-896f-47c5-bb6b-031f783e2a44 887_1687230919391.js:2:388082
connected to room chat232 887_1687230919391.js:2:392213
avoiding flicker code - inside setTimeout(), assigning element.srcObject =
MediaStream { id: "{6782f628-f118-4596-ae13-e935cc0828e9}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265433
could not playback audio DOMException: The fetching process for the media resource was aborted by the user agent at the user's request.
    vo https://chat.nkonev.name/887_1687230919391.js:2
887_1687230919391.js:2:263316
isMobileFirefox =  false  in case Mobile Firefox simulcast for video tracks will be disabled 887_1687230919391.js:2:395323
Publishing local audio screen=false track with name track_audio__screen_false_78dd2060-5420-434f-8802-5c0e9dcd3772 and simulcast true 887_1687230919391.js:2:395564
LocalTrackPublished to room.name chat232 887_1687230919391.js:2:391095
LocalTrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1687230919391.js:2:391158
Processing audio track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1687230919391.js:2:387716
candidatesWithoutAudio
Array []
 candidateToAppendAudio null 887_1687230919391.js:2:387863
Setting source audio for videoRef=
<video id="local-136e8aed-633c-4c5d-890d-a8ab58f0106a" class="video-element video-element-top" data-v-6a74c99a="" autoplay="" playsinline="" style="">  track=
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
  audio tag id= local-136e8aed-633c-4c5d-890d-a8ab58f0106a , enabled= true 887_1687230919391.js:2:383200
Audio track was set TR_AMHgx76R5ZdzH3 to local-136e8aed-633c-4c5d-890d-a8ab58f0106a 887_1687230919391.js:2:388082
Published track sid= TR_AMHgx76R5ZdzH3  kind= audio 887_1687230919391.js:2:395775
Publishing local video screen=false track with name track_video__screen_false_c3793d0c-4cc5-448e-84a9-174c26724117 and simulcast true 887_1687230919391.js:2:395564
LocalTrackPublished to room.name chat232 887_1687230919391.js:2:391095
LocalTrackPublished to room
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, state: Getter & Setter, activeSpeakers: Getter & Setter, audioEnabled: Getter & Setter, connect: Getter & Setter, connectSignal: Getter & Setter, applyJoinResponse: Getter & Setter, attemptConnection: Getter & Setter, … }
887_1687230919391.js:2:391158
Processing audio track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1687230919391.js:2:387716
Skipping audio
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1687230919391.js:2:387795
Processing video track
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
887_1687230919391.js:2:387194
candidatesWithoutVideo
Array [ {…} ]
 candidateToAppendVideo
Object { _uid: 2452, _isVue: true, __v_skip: true, _scope: {…}, "$options": {…}, _renderProxy: {…}, _self: {…}, "$parent": undefined, "$root": {…}, "$children": (5) […], … }
887_1687230919391.js:2:387341
Setting source video for videoRef=
<video id="local-136e8aed-633c-4c5d-890d-a8ab58f0106a" class="video-element video-element-top" data-v-6a74c99a="" autoplay="" playsinline="" style="">  track=
Object { _events: Getter & Setter, _eventsCount: Getter & Setter, _maxListeners: Getter & Setter, metadataMuted: Getter & Setter, handleMuted: Getter & Setter, handleUnmuted: Getter & Setter, kind: Getter & Setter, trackSid: Getter & Setter, trackName: Getter & Setter, source: Getter & Setter, … }
  video tag id= local-136e8aed-633c-4c5d-890d-a8ab58f0106a , enabled= true 887_1687230919391.js:2:383467
before avoiding flicker code 887_1687230919391.js:2:265047
avoiding flicker code - first condition passed : element.srcObject !== mediaStream, assigning element.srcObject =
MediaStream { id: "{6550b25b-188e-4e61-ba2e-4188bb4a8628}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265109
avoiding flicker code - second condition passed safari or ff and element instanceof HTMLVideoElement 887_1687230919391.js:2:265300
after avoiding flicker code 887_1687230919391.js:2:265623
Video track was set TR_VCABKQuypRM6wo to local-136e8aed-633c-4c5d-890d-a8ab58f0106a 887_1687230919391.js:2:387560
Published track sid= TR_VCABKQuypRM6wo  kind= video 887_1687230919391.js:2:395775
avoiding flicker code - inside setTimeout(), assigning element.srcObject =
MediaStream { id: "{6550b25b-188e-4e61-ba2e-4188bb4a8628}", active: true, onaddtrack: null, onremovetrack: null }
887_1687230919391.js:2:265433
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392
Got globalEvents event
Object { data: {…} }
main_1687230919391.js:2:40392

FYI Seems the bug has been fixed in Firefox 115

that's great to hear, thanks for the update 🙏


Cow: Watch theblissspa.in

Cow requests the watch of the watch_keyword theblissspa\.in. See the MS search here and the Stack Exchange search in text, in URLs, and in code.

theblissspa\.in has been seen in 1 true positive, 0 false positives, and 0 NAAs.

Approved by Jeff Schaller in Charcoal HQ


Support Commitment?

I like the look of this library a whole lot and I'm thinking of picking it up for a new project.
I'm just wondering what your feelings are regarding how committed you are to continuing development on it into the medium and long term?
Obviously, it's open source and I can't hold you to anything, but if you're already feeling like you've had enough, I might pick a different lib
Cheers!

No plans.


Feature request: Fish Shell

scoop install fish

Pretty please! Cygwin version is a nightmare!

Will not be implemented
Duplicate of ScoopInstaller/Main#903

Duplicate of ScoopInstaller/Main#903


Low contrast terminal output with corrupt characters

I'm on an Ubuntu 16.04 desktop, any ideas why my CLI output is so rough?

The spec reporter uses Unicode characters so your terminal needs to use utf8 and a font with those glyphs. It's likely the former in your case.

Seems like my terminal does support unicode (stock ubuntu 16.04 desktop), I switched between a few fonts. Any idea what code that glyph is supposed to be so i can verify explicitly ?

https://github.com/mochajs/mocha/blob/master/lib/reporters/base.js#L80-L93
Closing this out (see our travis ci builds to see the checkmark come out in color).


Error in simulator: Unable to resolve module react-native/Libraries/Components/ScrollResponder from node_modules/deprecated-react-native-listview/index.js in react native 0.71.1

did you find a fix for this?


How to specify the role claim key

Some keys may use " (e.g ."https://somedomain/key")  and will break the deployment. With the JWT_SECRET we can specify a base64 encoded string, but this is not possible with the ROLE_CLAIM_KEY

It's possible to have a json key with a domain name in role-claim-key, you'll have to escape the quotes ".
There's an example here: http://postgrest.org/en/v6.0/configuration.html#role-claim-key.

@steve-chavez I am aware that I can do this, however it will break the env-to-config script by producing a config with invalid line endings

Hmm, could that can be fixed in these lines?
https://github.com/PostgREST/postgrest-heroku/blob/c4ed3779c25ff1335f2636294d953deb1d7d6e2c/env-to-config#L21-L32
I'd appreciate your help with this, it's been a while since I've touched postgrest-heroku.

@steve-chavez I specifically think this:
".\"https://somedomain.example/key\""

breaks in line 27

I solved my issues by modifying env-to-config manually as in https://github.com/PostgREST/postgrest-heroku/compare/master...eventzimmer:master
However this is bad practice and I do not know how to fix it. It's just a hint for anyone stuck with a similar problem.

Notably when trying to use the JWT_SECRET and ROLE_CLAIM_KEY with quoted strings, it will produce an invalid config like mentioned here: https://github.com/PostgREST/postgrest/issues/937

this should be fixed with this PR https://github.com/PostgREST/postgrest-heroku/pull/40 as it removes the use of the env-to-config scripts in favour of env vars


Cloned, Ran Setup, but not resolving URL in browser..

I'll need a lot more info, but sounds like your DNS isn't resolving. Try m2.localhost domain.


LGTM


Fix log message of BrokerResource Setup() errors

Fixes wrong log message of BrokerResource.Setup()  errors

Good catch, and thank you!


Add a @apply decorator

In some cases it would be very useful to provide a custom apply function that the contract uses instead of the generated one
For example a contract with just this:
export function apply(receiver: u64, firstReceiver: u64, action: u64): void {
	if (receiver != firstReceiver) {
		requireRecipient(Name.fromString("account"))
	}
	return;
}

commit aa450d7555d001b908a4d3c44147d8624abdb404 should satisfy your need.

Yup that works!
One interesting thing though is that code from ascdk here is 4KB while same code from blanc++ is 124 bytes
ascdk code
import { Name, requireRecipient } from "as-chain"

@contract
class ForwardedContract {}

export function apply(receiver: u64, firstReceiver: u64, action: u64): void {
	if (receiver != firstReceiver) {
        requireRecipient(Name.fromString("sf"))
	}
	return;
}

blanc++
#include <eosio/eosio.hpp>

class [[eosio::contract]] forwarder : public eosio::contract {
public:
   using contract::contract;
};

extern "C" {
   [[eosio::wasm_entry]]
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) {
      if(code != receiver) {
         require_recipient("sf"_n);
         require_recipient("sf"_n);
      }
   }
}

Ah I can achieve same result with this:
export declare function require_recipient(name: u64): void

@contract
class ForwardedContract {}

export function apply(receiver: u64, firstReceiver: u64, action: u64): void {
	if (receiver != firstReceiver) {
        require_recipient(14033216438886465536);
	}
	return;
}


[derive] Suppress non_camel_case_types...

...in derive-generated code.
Closes #2051

Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 88.04%. Comparing base (e3b2ec1) to head (7674ad0).

Additional details and impacted files
@@            Coverage Diff             @@
##           v0.8.x    #2057      +/-   ##
==========================================
+ Coverage   87.64%   88.04%   +0.39%
==========================================
  Files          16       16
  Lines        6016     5983      -33
==========================================
- Hits         5273     5268       -5
+ Misses        743      715      -28

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

Backporting in #2060.


Support for aws session_token

AWS offers a third component of aws-credentials: access_key_id + secret_access_key + session_token, see LINK (and livekit/egress currently only supports two of them).
I've already asked the same question on livekit/slack LINK. I was directed to this place by cool people, for which I thank them.
PS: I tried passing the session_token via metadata, but it doesn't seem to work (mp4 file wasn't placed on S3), like:
            …
            "s3": {
                "access_key": "<access_key_id>",
                "secret": "<secret_access_key>",
                "metadata": {
                    "X-Amz-Security-Token": "<session_token>"
                },
                …
            }
            …

(the aws documentation does not confirm that this should work at all, links: Working with object metadata - Amazon Simple Storage Service, Using temporary credentials with AWS resources - AWS Identity and Access Management (amazon.com), Signing and authenticating REST requests - Amazon Simple Storage Service)

Did they fail the tests or do I need to do something extra?

Is there any way I can help with this (any tip?), or do I just have to patiently wait for someone from livekit (like you)?

Is there any way I can help with this (any tip?), or do I just have to patiently wait for someone from livekit (like you)?

I just merged https://github.com/livekit/protocol/pull/734 yesterday, can you update protocol and use SessionToken from the S3Upload in the request as well? I'll run the tests and merge after that

Okej 😅 (but today I tried 'golang getting started' first time 😄)
To be clear, I run these commands in the egress dir-repo:
❯ go mod download
❯ go get<EMAIL_ADDRESS>go: downloading golang.org/x/mod v0.17.0
go: upgraded github.com/livekit/protocol v1.16.1-0.20240513145257-511f517b1abf => v1.17.1-0.20240612003900-1dd95af54240
go: upgraded github.com/livekit/psrpc v0.5.3-0.20240403150641-811331b106d9 => v0.5.3-0.20240526192918-fbdaf10e6aa5

This also updated the version of livekit/psrpc and added dependencies to golang.org/x/mod, see: LINK.

Hey, is there a known ETA release date for the next version of egress (and next deploy to livekit cloud/prod)?
I'm asking in the context of session token support.


No notifications on iPhone

Nice app, thanks. We need it for iPhone.

No problem loggin in all go as it should
All users and Clients show as is

I do have a problem, getting a notification I get the alarm signal but can't see any message.
Also no old messages at all in the iPhone.

gotify has been recreated
igotify exited with code 0
igotify has been recreated
igotify exited with code 0
igotify has been recreated
gotify   | Starting Gotify version 2.4.0@2023-09-17-08:24:00
gotify   | Started Listening for plain HTTP connection on :80
igotify  | File is created.
igotify  | Client - Token:
igotify  | Gotify - Url: ws://gotify/stream?token=
igotify  | Client connecting...Done!
gotify   | 2024-01-10T14:41:36+02:00 | 200 |     4.07984ms |     <IP_ADDRESS> | GET      "/stream?token=[masked]"
igotify  | Reconnection happened, type: Initial
igotify  | info: Microsoft.Hosting.Lifetime[14]
igotify  |       Now listening on: http://[::]:8080
igotify  | info: Microsoft.Hosting.Lifetime[0]
igotify  |       Application started. Press Ctrl+C to shut down.
igotify  | info: Microsoft.Hosting.Lifetime[0]
igotify  |       Hosting environment: Production
igotify  | info: Microsoft.Hosting.Lifetime[0]
igotify  |       Content root path: /app
gotify   | 2024-01-10T14:41:37+02:00 | 200 |    2.217134ms |    | GET      "/application"
gotify   | 2024-01-10T14:41:37+02:00 | 200 |    8.632602ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:41:43+02:00 | 200 |    1.738538ms |    | GET      "/application"
gotify   | 2024-01-10T14:41:43+02:00 | 200 |    4.985731ms |    | GET      "/current/user"
gotify   | 2024-01-10T14:41:43+02:00 | 200 |    1.349784ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:41:46+02:00 | 200 |    3.541318ms |    | GET      "/current/user"
gotify   | 2024-01-10T14:41:46+02:00 | 200 |    1.386348ms |    | GET      "/application"
gotify   | 2024-01-10T14:41:47+02:00 | 200 |    2.404043ms |    | GET      "/stream?token=[masked]"
gotify   | 2024-01-10T14:41:50+02:00 | 200 |   81.480124ms |    | POST     "/message"
igotify  | Message converted: {"id":4,"appid":1,"message":"\nThis is a test of the notification target 'Gotify'\n","title":"Test notification","priority":1,"extras":{"clientdisplay":{"contentType":"text/markdown"}},"date":"2024-01-10T14:41:50.341571427+02:00"}
igotify  |
gotify   | 2024-01-10T14:41:57+02:00 | 200 |    1.233067ms |    | GET      "/application"
gotify   | 2024-01-10T14:41:57+02:00 | 200 |    3.263905ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:42:04+02:00 | 200 |    1.706637ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:42:07+02:00 | 200 |    6.773183ms |    | GET      "/application"
gotify   | 2024-01-10T14:42:07+02:00 | 200 |    1.133712ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:44:09+02:00 | 200 |    6.571001ms |    | GET      "/application"
gotify   | 2024-01-10T14:44:09+02:00 | 200 |    1.467014ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:44:15+02:00 | 200 |    9.005309ms |    | GET      "/current/user"
gotify   | 2024-01-10T14:44:16+02:00 | 200 |    1.177752ms |    | GET      "/application"
gotify   | 2024-01-10T14:44:16+02:00 | 200 |    1.200915ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:44:25+02:00 | 200 |    3.418988ms |    | GET      "/client"
gotify   | 2024-01-10T14:44:28+02:00 | 200 |    1.420087ms |    | GET      "/user"
gotify   | 2024-01-10T14:44:33+02:00 | 200 |    3.435814ms |    | GET      "/client"
gotify   | 2024-01-10T14:44:34+02:00 | 200 |    1.438739ms |    | GET      "/user"
gotify   | 2024-01-10T14:44:40+02:00 | 200 |     103.791µs |    | GET      "/version"
igotify  | warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
igotify  |       Failed to determine the https port for redirect.
gotify   | 2024-01-10T14:44:43+02:00 | 200 |     7.79832ms |    | GET      "/application"
gotify   | 2024-01-10T14:44:43+02:00 | 200 |    1.289257ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:44:52+02:00 | 200 |   20.346748ms |    | POST     "/message"
igotify  | Message converted: {"id":5,"appid":1,"message":"\nThis is a test of the notification target 'Gotify'\n","title":"Test notification","priority":1,"extras":{"clientdisplay":{"contentType":"text/markdown"}},"date":"2024-01-10T14:44:52.437477394+02:00"}
igotify  |
gotify   | 2024-01-10T14:44:54+02:00 | 200 |    1.068236ms |    | GET      "/application"
gotify   | 2024-01-10T14:44:54+02:00 | 200 |    3.256869ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:45:06+02:00 | 200 |   16.641235ms |    | POST     "/message"
igotify  | Message converted: {"id":6,"appid":2,"message":"\nThis is a test of the notification target 'gotify-notifications'\n","title":"Test notification","priority":1,"extras":{"clientdisplay":{"contentType":"text/markdown"}},"date":"2024-01-10T14:45:06.308357671+02:00"}
igotify  |
gotify   | 2024-01-10T14:45:08+02:00 | 200 |    1.090436ms |    | GET      "/application"
gotify   | 2024-01-10T14:45:08+02:00 | 200 |    5.502843ms |    | GET      "/message?since=0"
gotify   | 2024-01-10T14:45:10+02:00 | 200 |    1.005231ms |    | GET      "/application"
gotify   | 2024-01-10T14:45:10+02:00 | 200 |   16.426426ms |    | GET      "/message?since=0"

Yes I have a token.
What I see is the popup and heare the alarm

Sorry but I don't know where you're problem is when you getting the push notifications.

please provide us screenshots from your gotify webside, where you can see the previous alerts
also provide us a screenshot of your app on the iphone
do you have this problem in your LAN or/and outside of it?
is your igotify external reachable?
do you have setup different users?

It's fixed. I had 2 users and switching back to the first fixed the issue.


LEAN-3030: Fix for circural import causing manuscript to be undefined in dev mode

@mnatsheh we can merge it without testing, this is a minor fix for a dev env problem only.


add more maintainers?

hi @carymrobbins I am wondering if you would consider adding more maintainers to this project? I myself will be more than happy to help.

Thanks @kailuowang for reaching out! I've created a new team for newtype maintainers and have added you to it. The help is absolutely appreciated, thank you!


How to serve Temporary directory?

I have tried:
server.serveDirectory(URL(string: NSTemporaryDirectory())!) server.serveDirectory(URL(fileURLWithPath: NSTemporaryDirectory()))
but nothing works. I managed to serve main bundle, but I cannot serve Temp. Please help :)

It was my mistake. This worked:
server.serveDirectory(URL(fileURLWithPath: NSTemporaryDirectory()), "/tmp")


adding refresh functionality in watch_poll which was not implemented …

Although the documentation of method def watch_poll(self, watch, refresh=False, callback=None): had following text:
If refresh is True, then all points on the watch will be updated, not         just those that have changed since the last poll.
, the parameter refresh was unused and hence above functionality as stated on documentation wasn't obtained.
I have added following lines to use refresh parameter.
if refresh:
            grid.metadata['refresh'] = hszinc.MARKER

Coverage decreased (-0.03%) to 39.422% when pulling c47565a9b9cdab1e3b24e4a0ff03156c086f33dc on itsmeccr:watchPoll_refresh into 9a3249bd502a44612f70e4a9431b60a1913f6e81 on ChristianTremblay:master.

Coverage decreased (-0.03%) to 39.422% when pulling c47565a9b9cdab1e3b24e4a0ff03156c086f33dc on itsmeccr:watchPoll_refresh into 9a3249bd502a44612f70e4a9431b60a1913f6e81 on ChristianTremblay:master.

Coverage decreased (-0.03%) to 39.422% when pulling c47565a9b9cdab1e3b24e4a0ff03156c086f33dc on itsmeccr:watchPoll_refresh into 9a3249bd502a44612f70e4a9431b60a1913f6e81 on ChristianTremblay:master.

Ahh whoopsie, I missed processing that argument.  Well spotted. :-)

This should go into develop, not master; master is for stable releases.


New subplot foundation for Plotly backend

Overview
This PR introduces a new foundation for combining plotly elements into a figure.
Background
Currently, the plotly backend makes use of the plotly.tools.make_subplots function to support laying out multiple elements in a single plotly figure.  This function is pretty flexible when working with Cartesian trace types, but it has limited support for 3D traces and no support for other trace types. Additionally, it cannot be used recursively so it's not possible to use make_subplots to build a GridSpace figure and then make_subplots again to layout multiple GridSpace views in a single figure.
PR Notes
There is a pretty detailed commit log, but here are the two top-level goals:
Replace make_subplots with figure_grid
This PR replaces the use of make_subplots with a new figure_grid function.  This function inputs a 2D list of figure dict instances, along with optional spacing arguments, and returns a new figure that is the combination of all of the input figures.  It handles all plotly trace types along with annotations, shapes, and images that are specified in Cartesian axis coordinates.  It also works fine recursively, so it is now possible to, for example, layout a GridSpace next to a HoloMap.
I may eventually try to roll this functionality into plotly.py directly, but it would need to be a lot more general, so I'd rather start in Holoviews where we have control over how figures are constructed.
Replace graph_objs with dicts at the Element level
This PR also changes the elements and layouts to work with dict instances rather than graph_objs instances. The graph_objs in version 3+ perform a lot more validation than in version 2, which is great when a user is directly building their own figure but it does have a performance cost.  For a system like Holoviews that is performing lots of iterative construction, I think it's better to build up the figure using raw dict and list instances and then convert it to a graph_objs.Figure object for validation just before rendering.
I'm not sure if this was the best place for it, but I added the step to convert the figure dict to a Figure instance to the _figure_data method of PlotlyRenderer.
Usage highlights
Here are some examples of layouts that did not work previously
3D plots in a layout
import numpy as np
import holoviews as hv
hv.notebook_extension('plotly')

y,x = np.mgrid[-5:5, -5:5] * 0.1
heights = np.sin(x**2+y**2)
scatt3d = hv.Scatter3D(zip(x.flat,y.flat,heights.flat))
scatt3d+scatt3d.options(color_index=2, size=5, cmap='fire')

Tables in a layout
import holoviews as hv
hv.extension('plotly')

gender = ['M','M', 'M','F']
age = [10,16,13,12]
weight = [15,18,16,10]
height = [0.8,0.6,0.7,0.8]

table = hv.Table((gender, age, weight, height), ['Gender', 'Age'], ['Weight', 'Height'])
table.select(Gender='M') + table.select(Gender='M', Age=10)

Note: I still want to replace this figure_factory table with the plotly table trace, but using the figure factory implementation here shows how annotations are merged and maintained successfully.
GridSpace inside a layout
import numpy as np
import holoviews as hv
hv.extension('plotly')

def sine_curve(phase, freq):
    xvals = [0.1* i for i in range(100)]
    return hv.Curve((xvals, [np.sin(phase+freq*x) for x in xvals]))

phases      = [0, np.pi/2, np.pi, 3*np.pi/2]
frequencies = [0.5, 0.75, 1.0, 1.25]
curve_dict_2D = {(p,f):sine_curve(p,f) for p in phases for f in frequencies}

gridspace = hv.GridSpace(curve_dict_2D, kdims=['phase', 'frequency'])
hmap = hv.HoloMap(gridspace)
hmap + hv.GridSpace(hmap)

Note that the GridSpaces shared x-axes and y-axes are maintained when placed inside a larger layout.
Performance
The plotly backend had felt a bit sluggish to me compared to bokeh and matplotlib, but with these changes it's much faster that it was, and faster than the other backends in some cases.  I'm not sure how to time this exactly, but here's a GIF of the display time for a layout of two 4x4 GridSpaces using each backend

Thanks for taking a look, and please let me know if you have any questions!

Wow, cool!

@jonmmease You continue to amaze me! Is this in a good place to start review? We were about to declare a feature freeze, but it would be really great to get these improvements into 1.11.0.

Haha, thanks @philippjfr 🙂  Yeah, this is good to go from my end (pending tests)

I'll point out a few things but they're all optional and I'd be happy to fix them up subsequently.

I'd be happy to merge this PR as is, thanks for the detailed docstrings! I'll probably have to play around a bit to get a good feel for the way the figure merge, subplot merging and figure grid code works but this seems like a very solid foundation to build on.
One thing I'd be happy to do at this point is to remove the big warning about the experimental nature of the backend. I may also work on porting the new so called dim transforms to the plotly backend to allow mapping dimension values onto any visual property and thereby replace the horrible color_index options.

The reason for the warning is that we aren't using the Plotly backend for our own projects at this time, and so its maintenance can't be folded into anything we're working on.  I'd be happy to remove the warning as long as someone were looking out for it even a little bit...

Hi @philippjfr @jlstevens @jbednar ,
Thanks for the kind words and for looking over and merging this PR so quickly!  My inclination would be to hold off on removing the warning for 1.11 and then revisit it again for 1.12. I'll email you some thoughts/context on the maintainership question this evening, but my general plan at this point is to spend some time over the next month or so getting to know the code base better by picking off some items from https://github.com/ioam/holoviews/issues/3196.


How can I push my refactored code here?

How can I push my refactored code here?
Hello everyone, my name is Wang Sutan, a programming enthusiast from China. I have refactored this ASCII art project.
Recently, the inappropriate use of this project by a well-known Chinese blogger, He Tongxue, has made this library known to many Chinese people. I believe that the actions of He Tongxue's team have damaged the image of Chinese programmers. I took this opportunity to refactor the project, with the first goal being to understand the project and learn the related technologies, and the second goal is to try to showcase a good image of Chinese programmers.
The basic logic of the original project is largely correct, but the code has a low degree of modularity and lacks readability. I mainly did the following work (you can also refer to this article):

Unified the management of core data related to characters.
The function get_args() for reading command line arguments has been decoupled in terms of parameter passing.
Completely refactored the algorithms related to ASCII art into several functions. In this process, I even discovered a significant flaw in the original code, which is that the original project had serious size issues when dividing a string of characters on a long strip of images. When I tried to divide Chinese characters, the result was chaotic. Now it has been fixed.
Added and improved type annotations.

I also have a certain understanding of Chinese character culture, and I took this opportunity to select some interesting Chinese characters and put them into the dictionary.
I obtained the code and resources by directly downloading the .zip file. The new code has been placed in my own repository. I don't know how to push my modifications to the original project, can anyone tell me?
My refactoring may introduce some new issues, and I welcome everyone to provide more opinions and suggestions.
如何将我重构的代码推送过来？
大家好，我是来自中国的编程爱好者王苏谈，重构了这个字符画项目。
近期，中国知名博主何同学对这个项目的不当使用，使得这个库被很多中国人知道。本人认为，何同学团队的做法损害了中国程序员的形象。我趁此机会，将该项目进行了重构，目的一是了解该项目，学习相关技术，二是尝试展现我们中国程序员的一种良好形象。
原项目的基本逻辑大体上是正确的，但是代码的模块化程度较低，缺乏可读性。我主要做了这些工作（还可以参考这篇文章）：

将与字符相关的核心数据统一起来管理。
读取命令行参数的函数get_args()传递参数的方式实现了解耦。
彻底重构了字符画相关的算法，做成了若干函数。在这个过程中，甚至发现了原代码的重大缺陷，就是原项目在划分一长条的图片上的一串字符时，尺寸是有严重问题的。我尝试划分汉字的时候，结果是混乱的。现在也改好了。
添加和完善了类型注解。

我还对中国汉字文化有一定的了解，借此机会，挑选了一些好玩的汉字，放到字典中。
我是通过直接下载.zip的方式获取代码和资源的，新的代码放到了自己的仓库中。不知道怎么将我的修改推送到原项目，大家能告诉我吗？
我的重构也许会引入一些新的问题，欢迎大家多提意见建议。

Since the HTX event a few code-related issues have been created, all without any response from @vietnh1009 . I suspect he is not willing to take time maintaining the code anymore, the code is really old.
Instead of trying to get your changes merged, I suggest publish your work to PyPI as a continuation of this original repo, like I do.


Installation on Mac fails....

SignaldeMacBook-Pro:~ signal$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
Press RETURN to continue or any other key to abort
==> Downloading and installing Homebrew...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (27/27), done.
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Failed during: git fetch origin master:refs/remotes/origin/master --tags --force
SignaldeMacBook-Pro:~ signal$  git config http.postBuffer 524288000
fatal: not in a git directory
SignaldeMacBook-Pro:~ signal$ git config --global http.lowSpeedLimit 0
SignaldeMacBook-Pro:~ signal$ git config --global http.lowSpeedTime 999999
SignaldeMacBook-Pro:~ signal$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
Press RETURN to continue or any other key to abort
==> Downloading and installing Homebrew...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (27/27), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Failed during: git fetch origin master:refs/remotes/origin/master --tags --force
SignaldeMacBook-Pro:~ signal$

Mobile hotspot  or WIFI all try,All failure.
I tried it five times and failed every time.
Every time it fails here
Press RETURN to continue or any other key to abort
==> Downloading and installing Homebrew...
remote: Enumerating objects: 35, done.
remote: Counting objects: 100% (35/35), done.
remote: Compressing objects: 100% (27/27), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Failed during: git fetch origin master:refs/remotes/origin/master --tags --force
SignaldeMacBook-Pro:~ signal$


make RRID a PIDName

find places where rrid is used
add "Research Resource Identifiers" to the enum of registries
make rrid a PIDname where the registry is "Research Resource Identifiers"

RRID already expects a PIDName, but the rest has been done


Fix long words breaking summaries

What is the context of this PR?
Long words are breaking summaries and causing elements to be pushed off the page this PR will add css to break long words onto multiple lines and hyphenate them
How to review

Tests pass
Change and example to have a long word in it to see if the word is broken onto multiple lines

 Issue #770: Long words breaking summary


Promiscious mode needed on network device

To access the IPs from outside the docker containers it is necessary to set the network adapter into promiscuous mode.
In Ubuntu this is possible with:
ip link set eth1 promisc on
Maybe you could add a hint to the readme file?

You are correct. Docker does this via the MACVLAN network driver.
 The advantage of using Compose with the MACVLAN driver is that Docker should automatically configure promiscuous mode for you when the containers start and de-configure it when the containers are stopped.
Easy-NMOS has been extensively tested under Ubuntu on both 18.04 and 20.04 LTS releases and manually enabling promiscuous mode was not required.
Did you correctly configure your "parent" adapter in the Docker-compose.yml file? Could you share your server configuration (particularly your NIC vendor/driver), your Docker version and Compose version?
Thanks...

Thank you for your detailed explanation. Seems you are right and some other setting might be the reason promiscuous mode was not working for me (but now it works):
I'm using a Ubuntu 18.04 VM (VMware) on a Windows host. After it was not working I enabled promiscuous mode in the vmx file of my VM (like described here: https://superuser.com/questions/1209497/how-do-you-enable-promiscuous-mode-in-vmware-workstation). Unsure if it's necessary and if its the only way to do this.
I'm using VMware Workstation Player 15.

Ahh... This makes much more sense now...
When running this stack inside VMs you do tend to have to authorise the use of promiscuous mode at the hypervisor layer. This is typically because you want to get the containers exposed to the external physical machine network via the Paravirtualized NIC in the VM. ie. so devices on your physical LAN can interact with the registry etc. With a hypervisor you are effectively adding a third-layer of abstraction to the implementation and that also needs configuring correctly. One alternative to this approach is to use SR-IOV - SR-IOV is another topic in itself.
I have had similar experiences when running using VirtualBox under Windows and VMWare Fusion under Mac.  Hypervisors tend to consider promiscuous mode as a potential security risk hence why explicit authority is needed. In my case, once promiscuous mode was enabled both hypervisors successfully worked.
Even though the containers have been tested under several hypervisors it's impossible to cover all the scenarios - all the hypervisors do slightly different things and in different ways. At this stage detailing support for hypervisor usage is beyond the resources of the project. If we have time we may add documentation for specific known scenarios to the README.md at some point.
In the interim, I'm quite happy to try and offer assistance on a case by case basis. Thanks.

Hi Rich!  I thought at first I had a similar problem as this issue. After struggling around some I found my problem (which might be common for newbies like myself with docker) was that I was trying to run my browser on the same machine as my docker containers.  For my system it simply didn't work. I saw it referenced on a macvlan posting that it's by design. Worked fine when I accessed from another machine though.  Docker bridge network doesn't seem to have this behavior and I could run my browser on the same machine.
I might have missed it and it might be dependent on versions somehow but for my 18.04 Ubuntu that's how it works for me.  Maybe a little note on the Readme page if you confirm this is the behavior.
PS: Thanks for a great git repo!  I'm up and running now and registering my own local nodes.


fullscreen

Hello, I have a suggestion.
I'd like that opened windows will be fullscreen if it was opened from fullscreen and will be windowed if it was opened from windowed mode.
Now it always open in windowed mode.

Sounds like a good idea.
chrome.window.create does have a WindowState option, which can be set to create full screen windows. However, the documentation indicates that it is currently not fully supported.
However, it appears to be fully backwards compatible and on its way to Chrome stable. Hence, I'll experiment and add it to the plugin.
Thanks for the suggestion!

Does this work for you now?
If not, could you please add more details about which platform and version of Chrome are you using?

after update, this does not work. window is always opened in windowed mode.
I'm using Windows 7 64bit, Chrome Version 42.0.2311.90 m

Thanks for the information. I'll test it on a Windows machine and see how to address this issue.
PS: On my machine (Mac), full screen mode is preserved when the new window opens.


Objects are oddly sized

FIne tunre their box colliders, and their scale

Looks alot better and plays alot better via 1d2418a1227032998fdbe1ee0bfb2025214195c1


Re-index the corpora for stemmed highlighting functionality

In order to optimally use the new highlighting functionality, the existing corpora need to be re-indexed. To ease the process of updating this, only a single change needs to be made to the corpus definition, i.e. the setting updated_highlighting needs to be set to True in the main_content_mapping method, see example below for the speech field in parliamentary corpora:
        es_mapping = main_content_mapping(token_counts=True, stopword_analysis=True, stemming_analysis=True, updated_highlighting=True),

This needs to be updated for all corpora that we deem interesting/functional enough to have this functionality (and locally tested with a test set), pushed to acceptation/test/production, and then the corpus needs to be re-indexed. The progress on the corpora will be tracked here:

[ ] Dutch Annual Reports
[ ] Dutch Public Newspapers
[ ] Dutch Newspapers (Delpher)
[ ] Guardian-Observer
[ ] DIOPTRA-L
[ ] Periodicals
[ ] Times
[ ] Eighteenth Century Collections Online
[ ] Judicial System Netherlands
[ ] DBNL

Isn´t this a duplicate of #1281 ? If not, I would recommend against doing two re-indexing migrations simultaneously.

Uhmmm good question. @BeritJanssen ?

Yes, duplicate!

@Meesch , as for the Dutchnewspapers (Delpher), I hope that the correct mapping is added now that it's being reindexed from source? I wasn't actually planning to do any reindex operation on this large corpus if we get a new version soon anyway.


feat(dev): include CLI args in config file and allow overwrite

I hereby agree to the terms of the Singularity Data, Inc. Contributor License Agreement.
What's changed and what's your intention?
We use overwrite instead of override because the latter is a keyword in rust.
In RFC https://github.com/risingwavelabs/rfcs/pull/34, we decided that CLI args should be a subset of the config file containing user-facing options.
I realize that it's difficult to put the CLI args to existing sections of risingwave.toml for the following two reasons:

Configs such as host, prometheus_listen_addr's default values vary from worker types,  so they cannot be shared in the server section.
Configs such as async_stack_trace, health_check_listener_addr are much related to the worker type, so they don't fit well into the categorization of storage, streaming or batch which is based on modules (in terms of code).

So I used a new section for each worker type, i.e. meta (reusing the existing one), compute_ndoe, compactor, frontend and frontend. To distinguish them from the existing sections, we can say that each newly added sections are categorized by worker types (physically deployed), while the old ones are categorized by modules (in terms of code). The former applies to exactly one worker type, while the latter may apply to multiple.
The CLI args that each worker type accepts remain the same. They will overwrite a subset of the entries in the corresponding section (e.g. args of compactor overwrites [compactor] section)
In terms of maintainability, I have to admit writing the CLI-configurable fields 3 times (in xxxOpts, xxxConfig and the OverwriteConfig trait) is tedious, but using macro makes the code really messy. I believe the ultimate solution is the declarative approach, that is to generate source code and doc from a toml file.
Checklist

[x] I have written necessary rustdoc comments
~- [ ] I have added necessary unit tests and integration tests~
~- [ ] I have added fuzzing tests or opened an issue to track them. (Optional, recommended for new SQL features).~
[x] All checks passed in ./risedev check (or alias, ./risedev c)

Documentation
If your pull request contains user-facing changes, please specify the types of the changes, and create a release note. Otherwise, please feel free to remove this section.
Types of user-facing changes
Please keep the types that apply to your changes, and remove those that do not apply.

Installation and deployment
RisingWave cluster configuration changes

Release note
Please create a release note for your changes. In the release note, focus on the impact on users, and mention the environment or conditions where the impact may occur.
Refer to a related PR or issue link (optional)

I just realized the procedure macro may greatly simplify the code for CLI args and the overwrite logic. Let me give it a try.

We use overwrite instead of override because the latter is a keyword in rust.

You can r#override. Both lgtm though

I managed to use procedural macro to greatly simplify the overwriting logic, so that we can only write the rustdoc and fields once, and there will be no need to manually implement OverwriteConfig. Here's the example usage:
[https://github.com/risingwavelabs/risingwave/blob/d9310dc0649c50b69a68cbe1c35aec77da95c902/src/common/src/config.rs#L108-L161
It will expand to:
https://github.com/risingwavelabs/risingwave/blob/d9310dc0649c50b69a68cbe1c35aec77da95c902/src/common/proc_macro/src/lib.rs#L22-L100
And the doc is here:
https://github.com/risingwavelabs/risingwave/blob/d9310dc0649c50b69a68cbe1c35aec77da95c902/src/common/proc_macro/src/lib.rs#L22-L100
Maybe this approach is better? @fuyufjh @xxchan @BugenZhao @jon-chuang

I will take a look soon. BTW, did you take a look at crates for layered configuration like https://github.com/Xuanwo/serfig and https://github.com/mehcode/config-rs? 🤔

did you take a look at crates for layered configuration like https://github.com/Xuanwo/serfig and https://github.com/mehcode/config-rs? 🤔

They may be useful when reading from multiple supported sources (seems not to include CLI args) and merging them, but neither of them supports overwriting a subset of the fields from CLI args. So I think it's still necessary to write our own tool for this feature, and it gives more flexibility.

BTW, how do we tell if an CLI arg should accept env variable?

Right, I was so stupid to neglect the skip attribute in clap so I thought it was necessary to define a separate struct for overwrite 😅. Using clap and serfig I was able to create two XxxConfig, one from cli, one from the file, and merge them together. And the docs should be naturally preserved.

It looks good to use the proc macro to implement OverwriteConfig (its impl not reviewed yet though).

Does OverwriteConfig mean args overwrites env, and env overwrite file? If so, serfig already implemented this:

really usage from databend.

impl Config {
  pub fn load(with_args: bool) -> Result<Self> {
      // Parse arg first because we should respect `--config-file`.
      let mut arg_conf = Self::default();

      if with_args {
          arg_conf = Self::parse();
      }

      let mut builder: serfig::Builder<Self> = serfig::Builder::default();

      // Load from config file first.
      {
          let config_file = if !arg_conf.config_file.is_empty() {
              arg_conf.config_file.clone()
          } else if let Ok(path) = env::var("CONFIG_FILE") {
              path
          } else {
              "".to_string()
          };

          if !config_file.is_empty() {
              builder = builder.collect(from_file(Toml, &config_file));
          }
      }

      // Then, load from env.
      builder = builder.collect(from_env());

      // Finally, load from args.
      if with_args {
          builder = builder.collect(from_self(arg_conf));
      }

      Ok(builder.build()?)
  }
}

To use serfig, here are some notes: serfig will use Default to decide which value to take. So it's required to make sure all instances have the same default value.

Hostname, or IP address? 🥵
在 2023年1月28日，下午1:42，Zhidong Guo @.***> 写道：

@Gun9niR commented on this pull request.

In src/compute/src/lib.rshttps://github.com/risingwavelabs/risingwave/pull/7523#discussion_r1089650482:

#[derive(Parser, Clone, Debug)]
pub struct ComputeNodeOpts {
// TODO: rename to listen_address and separate out the port.

#[clap(long, default_value = "<IP_ADDRESS>:5688")]
pub host: String,

#[clap(long = "host")]
pub listen_addr: Option,

Right, but what if there are multiple machines...
—
Reply to this email directly, view it on GitHubhttps://github.com/risingwavelabs/risingwave/pull/7523#discussion_r1089650482, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGFKEGVHUKRR53ULVW3KPU3WUSWVFANCNFSM6AAAAAAUFKWHMM.
You are receiving this because you were mentioned.Message ID: @.***>

As discussed offline, adding new sections will make the config file more confusing and complicated, and some items are not suitable to put into any existing sections. So what we actually need is just an overwriting framework. For the sake of clarity, I will move the implementation to another PR.


get rid of rubygem-bundler as run-time requirement

If we install bundler gem under vendor/bundle/ruby/2.1.0 directory,
and since we had that directory as GEM_PATH in the vhost configuration,
we don't need rubygem-bundler rpm as a runtime requirement.
Bundler does not install itself if you add it at the Gemfile, thus we
need to install it with "gem install --install-dir ..."

It turned out to be much simpler than what I expected ...

LGTM, I just made a small comment.


SPIKE : Making permission boundaries as SCP's at account level

Describe the issue

We have added the Permission boundary(PB) to protect few resources created by SEA as well as the terraform overlay

The newly added PB is only added to the workload admin role, but still roles can be created without having the PB attached which is not we want

We either have to enforce the teams to add PB to every role they create, which might lead to lot of questions asked and support time from our side

One way is see if the PB policy can be converted to SCP policy applied on the account level and test if the State machine will automatically remove it or remove it on the next run

Additional context
Add any other context, attachments or screenshots
Definition of done

Add the SCP on an account and run the State machine and see if the SCP survives.

Added a test policy in the management account and attached it to a workload account and the ASEA removed it. So moving on to adding permission boundary to the dev_automation_role.


Let pointerdown propagate if running on touch screen

On touch screens text selection is triggered by a long press, so we can let pointerdown events pass through to OSD if we detect one. This fixes problems with panning and zooming on mobile browsers when text selection was enabled.

Codecov Report

Merging #31 into master will increase coverage by 0.26%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master      #31      +/-   ##
==========================================
+ Coverage   71.36%   71.62%   +0.26%
==========================================
  Files          11       11
  Lines         646      652       +6
  Branches      193      197       +4
==========================================
+ Hits          461      467       +6
  Misses        158      158
  Partials       27       27

Impacted Files
Coverage Δ

src/components/PageTextDisplay.js
95.89% <100.00%> (+0.36%)
:arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c66f387...1eb4ccc. Read the comment docs.


(trying to work with Travis:) Fix: crash when etherscan API returns malformed ERC20 transfer transaction data, with missing `to

@James-Sangalli I have no idea!


Fix emojis

:birthday: :balloon: :eyes: :tada: :fireworks: :champagne: :monkey: :dancer: :cow:  :man_dancing: :rocket:  :1st_place_medal:

Deploy preview for openbuildservice ready!
Built with commit efe6cb14e25896bd23d617c45dc15e8f35a897c7
https://deploy-preview-218--openbuildservice.netlify.com


Add a new synchronized onTaskStart to ThreadedTaskExecuter

Threading should provide an additional method:

onTaskStart(self, Task) this is called during/shortly after the execution of the Task in the main Thread of the Executer and before the onTaskFinish(self, Task) of the same Task.

Implement this using .asyncio instead of .concurrent ?

Solved in
https://github.com/leoprover/ltb/commit/f3bdf500342dbc56b5ac573861cbd8b0916fccc7
https://github.com/leoprover/ltb/commit/2f7ed3d199202f3aff25c7eb3b38e58eed1d53ed
still implemented with .concurrent


Panic when can't open ~/.docker/config.json

When publishing, if the docker config doesn't exists, a panic occurs:
[vincentlam@td-dsp01 crown-high-elk]$ ../artefactor_linux_amd64 publish --docker-registry registry.dsp.internal
Loading image from downloads/quay.io~ukhomeofficedigital~elasticsearch~~v1.5.1.docker.tar.
ReTagging image as registry.dsp.internal/elasticsearch:v1.5.1.
pushing image registry.dsp.internal/elasticsearch:v1.5.1
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x75a5f2]

goroutine 1 [running]:
github.com/appvia/artefactor/pkg/docker.GetAuth(0xc42036e570, 0x2a, 0x0, 0x0)
    /Users/vincent/go/src/github.com/appvia/artefactor/pkg/docker/config.go:17 +0x92
github.com/appvia/artefactor/pkg/docker.Push(0xc42036e570, 0x2a, 0xc42024fb48, 0x1)
    /Users/vincent/go/src/github.com/appvia/artefactor/pkg/docker/push.go:33 +0x83
github.com/appvia/artefactor/pkg/cmd.publish(0xda84c0, 0x0, 0x0)
    /Users/vincent/go/src/github.com/appvia/artefactor/pkg/cmd/publish.go:76 +0x5e8
github.com/appvia/artefactor/pkg/cmd.glob..func2(0xda84c0, 0xc420374300, 0x0, 0x2, 0x0, 0x0)
    /Users/vincent/go/src/github.com/appvia/artefactor/pkg/cmd/publish.go:23 +0x2b
github.com/appvia/artefactor/vendor/github.com/spf13/cobra.(*Command).execute(0xda84c0, 0xc420374260, 0x2, 0x2, 0xda84c0, 0xc420374260)
    /Users/vincent/go/src/github.com/appvia/artefactor/vendor/github.com/spf13/cobra/command.go:762 +0x468
github.com/appvia/artefactor/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xda8260, 0xda8260, 0xc42024ff78, 0x403dfc)
    /Users/vincent/go/src/github.com/appvia/artefactor/vendor/github.com/spf13/cobra/command.go:852 +0x30a
github.com/appvia/artefactor/vendor/github.com/spf13/cobra.(*Command).Execute(0xda8260, 0x1, 0x0)
    /Users/vincent/go/src/github.com/appvia/artefactor/vendor/github.com/spf13/cobra/command.go:800 +0x2b
github.com/appvia/artefactor/pkg/cmd.Execute()
    /Users/vincent/go/src/github.com/appvia/artefactor/pkg/cmd/artefactor.go:101 +0x2d
main.main()
    /Users/vincent/go/src/github.com/appvia/artefactor/cmd/artefactor/artefactor.go:21 +0x20

Fixed by #27


Convert unix timestamps on bans/invites/exempts to something human readable.

Is your feature request related to a problem? Please describe.
Currently the timestamps for bans are in unix time. Having to convert those on a website into a human readable format is a bit annoying.
/mode #channel b
#channel<EMAIL_ADDRESS>weber.freenode.net<PHONE_NUMBER>

Describe the solution you'd like
/mode #channel b
#channel<EMAIL_ADDRESS>weber.freenode.net December 18, 2019 16:41:51

Describe alternatives you've considered
Allow options for various time formats.
Dec 18, 2019 4:41:51 PM
12/18/19 4:41:51 PM
Additional context
Add any other context or screenshots about the feature request here.

Thanks for reporting in! "ban modes" is not something I've used myself, so this part of Convos hasn't received any love. I hope 1b5f313 improves this in version 3.01.


Better handling around grep/awk

This fixes #839.

Test egrep -ao instead of just -o to avoid selecting egrep when -a is not supported  (i.e., gnu-grep egrep is not available)
Use awk instead of gawk. gawk doesn't support the escape sequence passed, so it wouldn't anyway. But Non-GNU systems will usually have a different flavor of awk where the escape sequence does work.

This has been tested on:

CentOS 7
CentOS 8
Debian 10
FreeBSD
illumos (SmartOS)
Ubuntu 20.04

I can also test on others if that's helpful.

thx, merged


Why does using a redisson container slow down io.netty?

An Attempted Optimization:
I was benchmarking an application and realized that the majority of time was being spent waiting on a jedis socket.
The slowness appeared to be from the accumulated network round trip of a particular jedis call.

Seems like a good use-case for a cached redisson container, so I opted for SetMultimapCache.
And sure enough, it reduced the overall time spent in my function from 24% to .1%

A new problem:
However this seems to have caused even more time to be spent in io.netty.  So much so that the overall duration (from the client's perspective), is significantly slower.
Do you know why this is happening?  My understanding so far is that both grpc and redisson are using netty, and maybe they aren't playing well together?  Or I have some kind of bottleneck which is now being stressed further by optimizing the main worker thread.  Or I don't understand netty or redisson enough to see what's happening.
Attempts to fix:
I've tried to setup the resisson client in many different ways.
  static RedissonClient createRedissonClient(RedisShardBackplaneConfig config)
      throws IOException {

      Config redissonConfig = new Config();
      redissonConfig.setNettyThreads(1);
      NioEventLoopGroup eventLoop = new NioEventLoopGroup(1);
      //EpollEventLoopGroup eventLoop = new EpollEventLoopGroup(1);
      eventLoop.setIoRatio(1);
      redissonConfig.setEventLoopGroup(eventLoop);

      ClusterServersConfig finalConfig = redissonConfig.useClusterServers()
      .addNodeAddress(config.getRedisUri())
      .setCheckSlotsCoverage(false);

      // SingleServerConfig finalConfig = redissonConfig.useSingleServer()
      // .setAddress(config.getRedisUri());

      RedissonClient client = Redisson.create(redissonConfig);
      return client;
    }

I've tried a different number of nettythreads.  I've tried different eventloop groups with different thread counts.  I've tried changing the IO ratio to something lower/higher than 50.  If it helps, I'll show you the diff of how I integrated the container.  It basically just shows how I moved away from jedis calls in place of the redisson container:
@@ -905,70 +948,68 @@ public class RedisShardBackplane implements ShardBackplane {
   @Override
   public void adjustBlobLocations(
       Digest blobDigest, Set<String> addWorkers, Set<String> removeWorkers) throws IOException {
-    String key = casKey(blobDigest);
-    client.run(
-        jedis -> {
-          for (String workerName : addWorkers) {
-            jedis.sadd(key, workerName);
-          }
-          for (String workerName : removeWorkers) {
-            jedis.srem(key, workerName);
-          }
-          jedis.expire(key, config.getCasExpire());
-        });
+
+    String key = DigestUtil.toString(blobDigest);
+    casLookup.putAll(key,addWorkers);
+    for (String workerName : removeWorkers) {
+      casLookup.remove(key,workerName);
+    }
+    casLookup.expireKey(key,config.getCasExpire(),TimeUnit.SECONDS);
+
   }

   @Override
   public void addBlobLocation(Digest blobDigest, String workerName) throws IOException {
-    String key = casKey(blobDigest);
-    client.run(
-        jedis -> {
-          jedis.sadd(key, workerName);
-          jedis.expire(key, config.getCasExpire());
-        });
+
+
+    String key = DigestUtil.toString(blobDigest);
+    casLookup.put(key,workerName);
+    casLookup.expireKey(key,config.getCasExpire(),TimeUnit.SECONDS);
+
   }

   @Override
   public void addBlobsLocation(Iterable<Digest> blobDigests, String workerName) throws IOException {
-    client.run(
-        jedis -> {
-          JedisClusterPipeline p = jedis.pipelined();
-          for (Digest blobDigest : blobDigests) {
-            String key = casKey(blobDigest);
-            p.sadd(key, workerName);
-            p.expire(key, config.getCasExpire());
-          }
-          p.sync();
-        });
+
+    for (Digest blobDigest : blobDigests) {
+      String key = DigestUtil.toString(blobDigest);
+      casLookup.put(key,workerName);
+      casLookup.expireKey(key,config.getCasExpire(),TimeUnit.SECONDS);
+    }
+
   }

   @Override
   public void removeBlobLocation(Digest blobDigest, String workerName) throws IOException {
-    String key = casKey(blobDigest);
-    client.run(jedis -> jedis.srem(key, workerName));
+
+    String key = DigestUtil.toString(blobDigest);
+    casLookup.remove(key,workerName);
   }

   @Override
   public void removeBlobsLocation(Iterable<Digest> blobDigests, String workerName)
       throws IOException {
-    client.run(
-        jedis -> {
-          JedisClusterPipeline p = jedis.pipelined();
-          for (Digest blobDigest : blobDigests) {
-            p.srem(casKey(blobDigest), workerName);
-          }
-          p.sync();
-        });
+
+
+    for (Digest blobDigest : blobDigests) {
+      String key = DigestUtil.toString(blobDigest);
+      casLookup.remove(key,workerName);
+    }
   }

   @Override
   public String getBlobLocation(Digest blobDigest) throws IOException {
-    return client.call(jedis -> jedis.srandmember(casKey(blobDigest)));
+
+    String key = DigestUtil.toString(blobDigest);
+    Set<String> all = casLookup.get(key);
+    return getRandomSetElement(all);
   }

   @Override
   public Set<String> getBlobLocationSet(Digest blobDigest) throws IOException {
-    return client.call(jedis -> jedis.smembers(casKey(blobDigest)));
+
+    String key = DigestUtil.toString(blobDigest);
+    return casLookup.get(key);
   }

   @Override
@@ -979,7 +1020,13 @@ public class RedisShardBackplane implements ShardBackplane {
     client.run(
         jedis -> {
           for (Digest blobDigest : blobDigests) {
-            Set<String> workers = jedis.smembers(casKey(blobDigest));
+
+
+
+            String key = DigestUtil.toString(blobDigest);
+            Set<String> workers = casLookup.get(key);
+
+
             if (workers.isEmpty()) {
               continue;
             }

^ The diff shouldn't be that important, but I didn't want to leave anything out.  These are the changes I've made with the configured redisson client that result in speedup where I was trying to optimize, but signifcant slow down on the client side and increased time spent in io.netty?
Do you know why this is happening?  What else can I try?

my problem was that I was calling container.get(str) which returns an RSet<String> instead of a Set<string>.  I guess it gets casted in some kind of way and isn't a compile error.  Anyways, the application was slow, because the Set was broken and it was doing different logic.  I should have called casLookup.get(key).readAll() and everything is performant again.


Do you have Kawaii Clicks?

Please give me i will close this Issue when you answer also i dont have Discord.

What