Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add optional allocator #344

Merged
merged 5 commits into from
Jul 16, 2020
Merged

add optional allocator #344

merged 5 commits into from
Jul 16, 2020

Conversation

drakkan
Copy link
Collaborator

@drakkan drakkan commented Mar 14, 2020

after processing a packet we keep in memory the allocated slices and we reuse
them for new packets.
Slices are allocated in:

  • recvPacket
  • when we receive a sshFxpReadPacket (downloads)

The allocated slices have a fixed size = maxMsgLength.

Allocated slices are referenced to the request order id and are marked for reuse
after a request is served in maybeSendPackets.

The allocator is added to the packetManager struct and it is cleaned at the end
of the Serve() function.

This allocation mode is optional and disabled by default.

I tested several different approachs, please take a look at my branches here:

the included benchmark show that this is the better approach. Here are some profiling results:

Upload 1GB file

Showing nodes accounting for 1116.80MB, 97.66% of 1143.54MB total
Dropped 63 nodes (cum <= 5.72MB)
Showing top 10 nodes out of 16
      flat  flat%   sum%        cum   cum%
 1110.30MB 97.09% 97.09%  1110.30MB 97.09%  golang.org/x/crypto/ssh.(*connectionState).readPacket
       6MB  0.52% 97.62%       10MB  0.87%  golang.org/x/crypto/ssh.Marshal (inline)
    0.50MB 0.044% 97.66%    10.50MB  0.92%  golang.org/x/crypto/ssh.(*channel).adjustWindow
         0     0% 97.66%    17.95MB  1.57%  github.com/drakkan/sftpgo/sftpd.Configuration.handleSftpConnection
         0     0% 97.66%    17.95MB  1.57%  github.com/pkg/sftp.(*RequestServer).Serve
         0     0% 97.66%    15.45MB  1.35%  github.com/pkg/sftp.(*conn).recvPacket (inline)
         0     0% 97.66%        6MB  0.52%  github.com/pkg/sftp.(*packetManager).controller
         0     0% 97.66%    15.45MB  1.35%  github.com/pkg/sftp.recvPacket
         0     0% 97.66%    10.50MB  0.92%  golang.org/x/crypto/ssh.(*channel).Read
         0     0% 97.66%    10.50MB  0.92%  golang.org/x/crypto/ssh.(*channel).ReadExtended

Download 1GB file

Showing nodes accounting for 34.34MB, 80.94% of 42.43MB total
Showing top 10 nodes out of 131
      flat  flat%   sum%        cum   cum%
   15.84MB 37.34% 37.34%    15.84MB 37.34%  github.com/pkg/sftp.(*allocator).GetPage
       5MB 11.78% 49.12%     6.50MB 15.32%  golang.org/x/crypto/ssh.Marshal
    2.50MB  5.89% 55.01%     4.50MB 10.61%  github.com/pkg/sftp.orderedPackets.Sort
       2MB  4.71% 59.73%        2MB  4.71%  internal/reflectlite.Swapper
       2MB  4.71% 64.44%        2MB  4.71%  github.com/pkg/sftp.(*packetManager).incomingPacket
       2MB  4.71% 69.15%        2MB  4.71%  strings.genSplit
    1.50MB  3.54% 72.69%     1.50MB  3.54%  github.com/pkg/sftp.makePacket
    1.50MB  3.54% 76.22%     8.45MB 19.91%  github.com/pkg/sftp.fileget
       1MB  2.36% 78.58%        1MB  2.36%  golang.org/x/crypto/ssh.(*connectionState).readPacket
       1MB  2.36% 80.94%        1MB  2.36%  github.com/pkg/sftp.(*packetManager).readyPacket

Fixes #334

after processing a packet we keep in memory the allocated slices and we reuse
them for new packets.
Slices are allocated in:

- recvPacket
- when we receive a sshFxpReadPacket (downloads)

The allocated slices have a fixed size = maxMsgLength.

Allocated slices are referenced to the request order id and are marked for reuse
after a request is served in maybeSendPackets.

The allocator is added to the packetManager struct and it is cleaned at the end
of the Serve() function.

This allocation mode is optional and disabled by default
allocator.go Outdated Show resolved Hide resolved
allocator.go Outdated Show resolved Hide resolved
allocator.go Outdated Show resolved Hide resolved
allocator.go Show resolved Hide resolved
allocator.go Outdated Show resolved Hide resolved
request-server.go Outdated Show resolved Hide resolved
request-server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
request-server.go Show resolved Hide resolved
packet.go Outdated Show resolved Hide resolved
request-server.go Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
request-server.go Outdated Show resolved Hide resolved
server.go Outdated Show resolved Hide resolved
@drakkan drakkan force-pushed the allocator_pr branch 4 times, most recently from f5a3cb4 to 083e69c Compare March 16, 2020 23:14
@drakkan
Copy link
Collaborator Author

drakkan commented Mar 16, 2020

@puellanivis thank you for your review. Please let me know if I need to change other things.

request-server.go Outdated Show resolved Hide resolved
Other minor changes as per review comments
@drakkan drakkan changed the title add optional AllocationModeOptimized add optional allocator Mar 18, 2020
we can keep compatibility removing the error return value from
RequestServerOption
@puellanivis
Copy link
Collaborator

Wanted to add some feedback on circumstances on my end. I do intend to evaluate the last changes, and you’ve probably covered all the important stuff. But work has been nuts with the COVID stuff, and work from home, and everything has just been quite hectic here, and i have not been able to give this the attention it deserves.

I’m sure I’ll be back to being able to provide the help to get this improvement put in soon.

@drakkan
Copy link
Collaborator Author

drakkan commented Mar 26, 2020

@puellanivis no problem, take your time and thanks for all your suggestions

@drakkan
Copy link
Collaborator Author

drakkan commented Apr 11, 2020

The allocator is now enabled in SFTPGo. I don't expect any issue, anyway this patch will be now tested by more users. Thanks

@puellanivis
Copy link
Collaborator

Awesome. I think the code is probably all set here, so with some actual real-world testing, we can then have extra safety on top.

@eikenb
Copy link
Member

eikenb commented May 1, 2020

@puellanivis Do you think this is good to merge? I keep meaning to review it but I've just had no time. I had a bit today and did a quick skim review and things looked good. I'll trust your opinion and if you think it is ready, please go ahead and merge it (or let me know and I can do it if you don't want to).

@puellanivis
Copy link
Collaborator

Yeah, I think any concerns I would have would be lint-like comments anyways. The solid chunk of concerns have all be addressed.

@drakkan
Copy link
Collaborator Author

drakkan commented Jun 29, 2020

a polite ping here.

I would like to release SFTPGo 1.0.0 before July 15, do you think this patch can be merged before then?
If this is not possibile I'll continue to use my pkg/sftp branch for the release too, thank you!

we need a POSIX path filepath.IsAbs can give unexpected results on Windows
@puellanivis
Copy link
Collaborator

Oh, sorry. I was up-to-my-eyeballs in stuff as of late.

@puellanivis puellanivis merged commit 95fa324 into pkg:master Jul 16, 2020
@puellanivis
Copy link
Collaborator

We’ll probably need to release at least a version 1.11.1 right?

Should we instead do a 1.12? I think we’re reasonably backwards compatible that all users of the code will still work with the same behavior if untouched, right?

@drakkan
Copy link
Collaborator Author

drakkan commented Jul 16, 2020

We’ll probably need to release at least a version 1.11.1 right?

Should we instead do a 1.12? I think we’re reasonably backwards compatible that all users of the code will still work with the same behavior if untouched, right?

Thank you! Yes it should be full backwards compatible.

Please note that I pushed by mistake #355 to this branch (without the test case) since I included it in SFTPGo 1.0.0, do you want a patch to revert it? Or a patch to add the test case only? Sorry my bad

@puellanivis
Copy link
Collaborator

Uh, depends on if it’s actually a bug or not. Various parts of the SFTP standard dictate that we should be using POSIX path not per-OS filepath so… 🤷

@eikenb
Copy link
Member

eikenb commented Jul 19, 2020

Should we instead do a 1.12?

I think so. Not so much due to compatibility issues but to help highlight all the performance work drakkan contributed.

I'm going to add a 1.12.0 release milestone and add all the relevant issues/prs to it. So we have some semblance of a changelog.

@eikenb eikenb added this to the v1.12.0 milestone Jul 19, 2020
@drakkan drakkan deleted the allocator_pr branch November 26, 2020 08:04
@drakkan drakkan restored the allocator_pr branch November 26, 2020 08:04
@drakkan drakkan deleted the allocator_pr branch July 15, 2022 10:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Performance improvements
3 participants