[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-21 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r412199074



##
File path: 
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
##
@@ -954,7 +954,9 @@ protected IoWriteFuture doWritePacket(Buffer buffer) throws 
IOException {
 synchronized (encodeLock) {
 Buffer packet = resolveOutputPacket(buffer);
 IoSession networkSession = getIoSession();
-return networkSession.writePacket(packet);
+IoWriteFuture future = networkSession.writePacket(packet);
+buffer.rpos(buffer.wpos());
+return future;

Review comment:
   >> Ok, so the problem is in the assumptions about the writePacket.
   
   I did not mean that there is any problem with the call since the packet is 
obviously a different instance than the original buffer. If there is some 
similar optimization that needs to be done on the packet then indeed we need to 
make it **after** being informed (via a listener) that the packet has been 
consumed.





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-21 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r412195385



##
File path: 
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
##
@@ -954,7 +954,9 @@ protected IoWriteFuture doWritePacket(Buffer buffer) throws 
IOException {
 synchronized (encodeLock) {
 Buffer packet = resolveOutputPacket(buffer);
 IoSession networkSession = getIoSession();
-return networkSession.writePacket(packet);
+IoWriteFuture future = networkSession.writePacket(packet);
+buffer.rpos(buffer.wpos());
+return future;

Review comment:
   You are right - took me a bit to ensure that this is the case...





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-21 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r412178637



##
File path: 
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
##
@@ -954,7 +954,9 @@ protected IoWriteFuture doWritePacket(Buffer buffer) throws 
IOException {
 synchronized (encodeLock) {
 Buffer packet = resolveOutputPacket(buffer);
 IoSession networkSession = getIoSession();
-return networkSession.writePacket(packet);
+IoWriteFuture future = networkSession.writePacket(packet);
+buffer.rpos(buffer.wpos());
+return future;

Review comment:
   >>  So while the packet is yet to be written, the buffer won't be used 
anymore and is consumed at the time the buffer.rpos(buffer.wpos()) is called.
   
   That was not what I meant - `networkSession#writePacket` might be 
asynchronous - i.e., posts the buffer for writing and returns immediately - so 
when it attempt to access `rpos` it might use the wrong one since we override 
it.





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-21 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r412176392



##
File path: 
sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/SftpRemotePathChannel.java
##
@@ -524,13 +527,13 @@ protected void endBlocking(Object actionHint, boolean 
completed)
  * @param  reqModesThe required modes - ignored if {@code null}/empty
  * @throws IOException If channel not open or the required modes are not 
satisfied
  */
-private void ensureOpen(Collection reqModes) throws 
IOException {
+private void ensureOpen(Collection reqModes) throws IOException {

Review comment:
   +1





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-21 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r412176062



##
File path: 
sshd-sftp/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTransferTest.java
##
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sshd.client.subsystem.sftp;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.client.subsystem.sftp.fs.SftpFileSystem;
+import org.junit.Test;
+
+public class SftpTransferTest extends AbstractSftpClientTestSupport {

Review comment:
   >> I'll add it, but not sure when it's actually useful...
   
   My experience shows that it is possible for a unit test to fail due to some 
unforeseen dependency with some side-effect of some other test. However, if the 
order of the tests changes from one run to another (can happen if using a 
different JDK version) then the failure may become irreproducible. Therefore, 
the _surefire_ plugin is configured to run the classes in alphabetical order - 
but within each class we want to make sure the individual tests are also run in 
a predictable order. This way, if a unit test fails (for whatever reason - not 
only because of interaction with another test) we can re-produce it with a high 
probability.
   
   Of course, the down side is that if there is some interaction we don't know 
about we might not discover it until by some chance the lexicographical order 
changes. This can be managed by having a **separate** build profile that 
randomizes the methods, lists the chosen permutation and then runs the tests in 
that particular order. This way, if there is some unknown interaction between 
the tests we might detect it eventually and then reproduce it using the listed 
permutation order.





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-20 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r411554606



##
File path: sshd-sftp/pom.xml
##
@@ -85,6 +85,18 @@
 jzlib
 test
 
+
+org.testcontainers
+testcontainers
+1.12.5
+test
+
+
+org.testcontainers
+toxiproxy
+1.12.5
+test
+

Review comment:
   Even better...





This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



-
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org



[GitHub] [mina-sshd] lgoldstein commented on a change in pull request #123: SFTP transfer speeds, clean API

2020-04-20 Thread GitBox


lgoldstein commented on a change in pull request #123:
URL: https://github.com/apache/mina-sshd/pull/123#discussion_r411387849



##
File path: 
sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelAsyncOutputStream.java
##
@@ -107,9 +108,39 @@ protected synchronized void doWriteIfPossible(boolean 
resume) {
 if (total > 0) {
 Channel channel = getChannel();
 Window remoteWindow = channel.getRemoteWindow();
-long length = Math.min(Math.min(remoteWindow.getSize(), total), 
remoteWindow.getPacketSize());
-if (log.isTraceEnabled()) {
-log.trace("doWriteIfPossible({})[resume={}] attempting to 
write {} out of {}", this, resume, length, total);
+long length;
+if (remoteWindow.getSize() < total && total <= 
remoteWindow.getPacketSize()) {
+// do not chunk when the window is smaller than the packet size
+length = 0;
+// do a defensive copy in case the user reuses the buffer
+IoWriteFutureImpl f = new IoWriteFutureImpl(future.getId(), 
new ByteArrayBuffer(buffer.getCompactData()));
+f.addListener(w -> future.setValue(w.getException() != null ? 
w.getException() : w.isWritten()));
+pendingWrite.set(f);
+if (log.isTraceEnabled()) {
+log.trace("doWriteIfPossible({})[resume={}] waiting for 
window space {}", this, resume,
+remoteWindow.getSize());
+}
+} else if (total > remoteWindow.getPacketSize()) {
+if (buffer.rpos() > 0) {
+// do a defensive copy in case the user reuses the buffer

Review comment:
   This is a lot of code in a single method - can we somehow separate each 
case to a (protected) method - easier to read, debug, maintain...

##
File path: 
sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
##
@@ -954,7 +954,9 @@ protected IoWriteFuture doWritePacket(Buffer buffer) throws 
IOException {
 synchronized (encodeLock) {
 Buffer packet = resolveOutputPacket(buffer);
 IoSession networkSession = getIoSession();
-return networkSession.writePacket(packet);
+IoWriteFuture future = networkSession.writePacket(packet);
+buffer.rpos(buffer.wpos());
+return future;

Review comment:
   Doesn't this change the `rpos` while the session is writing the buffer ? 
Feels like this should be done only **after** packet has been written

##
File path: sshd-sftp/pom.xml
##
@@ -85,6 +85,18 @@
 jzlib
 test
 
+
+org.testcontainers
+testcontainers
+1.12.5
+test
+
+
+org.testcontainers
+toxiproxy
+1.12.5
+test
+

Review comment:
   If these 2 dependencies are always expected to have the same version 
let's use a property (e.g., `${testcontainers.version}` - this way if we 
upgrade one we will not forget to update the other (D.R.Y. principle)

##
File path: 
sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/SftpOutputStreamAsync.java
##
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sshd.client.subsystem.sftp.impl;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Objects;
+
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.OpenMode;
+import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.io.OutputStreamWithChannel;
+
+/**
+ * Implements an output stream for a given remote file
+ *
+ * @author mailto:dev@mina.apache.org";>Apache MINA SSHD Projec