Sunday, May 23, 2021

A simple pool leveraging guava cache and java concurrency apis

 A simple pool SimpleJschPool with no threads

I implemented recently a simple pool for the Jsch session leveraging guava cache and java concurrency APIs. Jsch is a tiny old library use by enterprises for mft/sftp files transfer. 

Jsch is not definitively a very convenient library but sometimes, as developers, using some specific tools is part of the job. 

This is irrelevant for the purpose of this sample demo project as the underlying solution is just a pool of something you don't want to create again and again.

  • 3 simple classes project. Comments welcome

https://github.com/bfayette/SimpleJschPool

I have tried common-pool which has the overhead of managing a threads pool.

Component of this solution

  • A Jsch Session Provider creates a new session when needed
  • A tickets Generator which provides unique ticket per request
  • A JVM cache (Guava) to save temporary the unique ChannelSft  per ticket
  • A semaphore to moderate tickets generation, hence channels allocation to requests
  • The ChannelSft is a non-thread-safe object so cannot be shared between threads. The semaphore helps us achieve this goal.



Read and parse text file with just plain java

 I'll show my implementation with some print screens. I'll add it to my GitHub later. So I'll be back

ResetOnCloseStream or ReusableInputStream.

Read multiple times an input stream is a common requirement with built-in implementation as per my search. Obviously, this is very interesting to limit application java footprint memory by copying. 

Say that you need to process a file but also send a copy somewhere for audit purposes. I looked at solutions like common io with the implementation of pipes stream. Other suggestions involve a copy of the underlying stream. For these solutions, we need to store them somewhere which is not very practicable.

Then the solution is to cook something with a markable or mark supported stream via for instance a Buffered Input Stream. We need these methods from the API :

public synchronized void mark(int readLimit)
public synchronized void reset() throws IOException
public boolean markSupported()

The mark method marks the current position which the beginning of the reading process. We use max integer values or any big integer value so we can get back to the zero position safely.  This is not my idea, please read this discussion from StackOverflow: https://stackoverflow.com/questions/924990/how-to-cache-inputstream-for-multiple-use


I've kept the name which is very intuitive. I just add a method for closing the decorated stream and convert if needed the inputStream to decorate to a markable inputStream.