Sunday, July 30, 2023

how to transfer oversized string over message system

for text based message system, if there's a limit of x KB, you can still transfer (~5 * x) KB by

  1. compressing the original payload
  2. encoding compressed binary to text
  3. sending it
receiver reverses the process to get original payload by
  1. testing to make sure message is encoded
  2. decoding it to compressed binary
  3. uncompressing decoded binary
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

String payload = """
        {
        }""";
System.out.printf("original size: %s bytes\n", payload.length());

ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos);
gos.write(payload.getBytes());
gos.close();
byte[] compressed = baos.toByteArray();
System.out.printf("compressed size: %s bytes\n", compressed.length);

String encoded = Base64.encodeBase64String(compressed);
System.out.printf("encoded size: %s bytes\n", encoded.length());

System.out.println("is message encoded? " + Base64.isBase64(encoded));
byte[] decoded = Base64.decodeBase64(encoded.getBytes());
System.out.printf("decoded size: %s bytes\n", decoded.length);

GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(decoded));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = gis.read(buffer)) > 0) {
    output.write(buffer, 0, bytesRead);
}
gis.close();
String uncompressed = output.toString();
System.out.printf("uncompressed size: %s bytes\n", uncompressed.length());


original size: 9450 bytes
compressed size: 1235 bytes
encoded size: 1648 bytes
is message encoded? true
decoded size: 1235 bytes
uncompressed size: 9450 bytes


Saturday, July 01, 2023

revisit timeout settings after 9 years

After almost 9 year, this is part 2, or an update to Are you setting Connect Timeout correctly? I'm going to give the best practice of setting connect timeout and read timeout for org.springframework.boot.web.client.RestTemplateBuilder as of Spring Boot 2.7.13.

Let's say it takes up to 0.1 sec to setup connection and 1 sec to receive response, then it's easy to understand you'll get org.apache.http.conn.ConnectTimeoutException if

return restTemplateBuilder
.rootUri(rootUri)
.basicAuthentication(username, password)
.setConnectTimeout(ofMillis(10))
.setReadTimeout(ofMillis(1000))
.build();

and java.net.SocketTimeoutException: Read timed out if

return restTemplateBuilder
.rootUri(rootUri)
.basicAuthentication(username, password)
.setConnectTimeout(ofMillis(100))
.setReadTimeout(ofMillis(100))
.build();

You can either set both timeouts

return restTemplateBuilder
.rootUri(rootUri)
.basicAuthentication(username, password)
.setConnectTimeout(ofMillis(100))
.setReadTimeout(ofMillis(1000))
.build();

or omit connect timeout and only set read timeout

return restTemplateBuilder
.rootUri(rootUri)
.basicAuthentication(username, password)
//.setConnectTimeout(ofMillis(100))
.setReadTimeout(ofMillis(1000))
.build();

however by setting connect timeout only and omitting read timeout, you'll get java.net.SocketTimeoutException: Read timed out

return restTemplateBuilder
.rootUri(rootUri)
.basicAuthentication(username, password)
.setConnectTimeout(ofMillis(100))
//.setReadTimeout(ofMillis(1000))
.build();

Let me rephrase what I said 9 years ago, don't set both timeout to be the same, which shows you don't know how network communication works.


Sunday, April 09, 2023

arrange displays and set resolution for mac

i've written few posts on resolution, but never on a mac. i did experience an issue with displays in macos recently. i have 2 external displays but macos (Ventura 13.2) can only identify one, so i just can't place or rotate the other one (it's not in System Settings - Displays page, and it's NaN-inch (0 × 0) in System Settings - General - About page).

luckily i found displayplacer after tried a few others that didn't help. it identifies all the displays, lists all the modes (resolution, herts, colour depth and scaling), so i can place them and set resolutions that are not even officially listed on specs. i got this by running the command for the 1st time:

$ ./displayplacer list                          

Persistent screen id: 

Contextual screen id: 

Type: 27 inch external screen

Resolution: 1920x1080

Hertz: 60

Color Depth: 8

Scaling:off

Origin: (0,0) - main display

Rotation: 0

Resolutions for rotation 0:

  mode 0: res:1920x1080 hz:60 color_depth:4

  mode 1: res:1920x1080 hz:60 color_depth:8 <-- current mode

  mode 2: res:1280x720 hz:60 color_depth:4

  mode 3: res:1280x720 hz:60 color_depth:8

  mode 4: res:720x480 hz:60 color_depth:4

  mode 5: res:720x480 hz:60 color_depth:8

  mode 6: res:640x480 hz:60 color_depth:4

  mode 7: res:640x480 hz:60 color_depth:8

  mode 8: res:1920x1080 hz:25 color_depth:4

  mode 9: res:1920x1080 hz:25 color_depth:8

  mode 10: res:1920x1080 hz:50 color_depth:4

  mode 11: res:1920x1080 hz:50 color_depth:8

  mode 12: res:720x576 hz:50 color_depth:4

  mode 13: res:720x576 hz:50 color_depth:8

  mode 14: res:1280x720 hz:50 color_depth:4

  mode 15: res:1280x720 hz:50 color_depth:8

  mode 16: res:720x480 hz:61 color_depth:4

  mode 17: res:720x480 hz:61 color_depth:8

  mode 18: res:640x480 hz:60 color_depth:4

  mode 19: res:640x480 hz:60 color_depth:8

  mode 20: res:800x600 hz:60 color_depth:4

  mode 21: res:800x600 hz:60 color_depth:8

  mode 22: res:1024x768 hz:60 color_depth:4

  mode 23: res:1024x768 hz:60 color_depth:8

  mode 24: res:1024x576 hz:60 color_depth:4

  mode 25: res:1024x576 hz:60 color_depth:8

  mode 26: res:1280x960 hz:60 color_depth:4

  mode 27: res:1280x960 hz:60 color_depth:8

  mode 28: res:1344x1008 hz:60 color_depth:4

  mode 29: res:1344x1008 hz:60 color_depth:8

  mode 30: res:1344x756 hz:60 color_depth:4

  mode 31: res:1344x756 hz:60 color_depth:8

  mode 32: res:1440x900 hz:60 color_depth:4

  mode 33: res:1440x900 hz:60 color_depth:8

  mode 34: res:1680x1050 hz:60 color_depth:4

  mode 35: res:1680x1050 hz:60 color_depth:8

  mode 36: res:1600x900 hz:60 color_depth:4

  mode 37: res:1600x900 hz:60 color_depth:8

  mode 38: res:1920x1200 hz:60 color_depth:4

  mode 39: res:1920x1200 hz:60 color_depth:8

  mode 40: res:2560x1440 hz:60 color_depth:4

  mode 41: res:2560x1440 hz:60 color_depth:8

  mode 42: res:2560x1600 hz:60 color_depth:4

  mode 43: res:2560x1600 hz:60 color_depth:8

  mode 44: res:640x480 hz:25 color_depth:4

  mode 45: res:640x480 hz:25 color_depth:8

  mode 46: res:800x600 hz:25 color_depth:4

  mode 47: res:800x600 hz:25 color_depth:8

  mode 48: res:1024x768 hz:25 color_depth:4

  mode 49: res:1024x768 hz:25 color_depth:8

  mode 50: res:1024x576 hz:25 color_depth:4

  mode 51: res:1024x576 hz:25 color_depth:8

  mode 52: res:1280x720 hz:25 color_depth:4

  mode 53: res:1280x720 hz:25 color_depth:8

  mode 54: res:1280x960 hz:25 color_depth:4

  mode 55: res:1280x960 hz:25 color_depth:8

  mode 56: res:1344x1008 hz:25 color_depth:4

  mode 57: res:1344x1008 hz:25 color_depth:8

  mode 58: res:1344x756 hz:25 color_depth:4

  mode 59: res:1344x756 hz:25 color_depth:8

  mode 60: res:1440x900 hz:25 color_depth:4

  mode 61: res:1440x900 hz:25 color_depth:8

  mode 62: res:1680x1050 hz:25 color_depth:4

  mode 63: res:1680x1050 hz:25 color_depth:8

  mode 64: res:1600x900 hz:25 color_depth:4

  mode 65: res:1600x900 hz:25 color_depth:8

  mode 66: res:1920x1200 hz:25 color_depth:4

  mode 67: res:1920x1200 hz:25 color_depth:8

  mode 68: res:2560x1440 hz:25 color_depth:4

  mode 69: res:2560x1440 hz:25 color_depth:8

  mode 70: res:2560x1600 hz:25 color_depth:4

  mode 71: res:2560x1600 hz:25 color_depth:8

  mode 72: res:640x480 hz:50 color_depth:4

  mode 73: res:640x480 hz:50 color_depth:8

  mode 74: res:800x600 hz:50 color_depth:4

  mode 75: res:800x600 hz:50 color_depth:8

  mode 76: res:1024x768 hz:50 color_depth:4

  mode 77: res:1024x768 hz:50 color_depth:8

  mode 78: res:1024x576 hz:50 color_depth:4

  mode 79: res:1024x576 hz:50 color_depth:8

  mode 80: res:1280x960 hz:50 color_depth:4

  mode 81: res:1280x960 hz:50 color_depth:8

  mode 82: res:1344x1008 hz:50 color_depth:4

  mode 83: res:1344x1008 hz:50 color_depth:8

  mode 84: res:1344x756 hz:50 color_depth:4

  mode 85: res:1344x756 hz:50 color_depth:8

  mode 86: res:1440x900 hz:50 color_depth:4

  mode 87: res:1440x900 hz:50 color_depth:8

  mode 88: res:1680x1050 hz:50 color_depth:4

  mode 89: res:1680x1050 hz:50 color_depth:8

  mode 90: res:1600x900 hz:50 color_depth:4

  mode 91: res:1600x900 hz:50 color_depth:8

  mode 92: res:1920x1200 hz:50 color_depth:4

  mode 93: res:1920x1200 hz:50 color_depth:8

  mode 94: res:2560x1440 hz:50 color_depth:4

  mode 95: res:2560x1440 hz:50 color_depth:8

  mode 96: res:2560x1600 hz:50 color_depth:4

  mode 97: res:2560x1600 hz:50 color_depth:8

  mode 98: res:960x540 hz:60 color_depth:4 scaling:on

  mode 99: res:960x540 hz:60 color_depth:8 scaling:on

  mode 100: res:960x540 hz:25 color_depth:4 scaling:on

  mode 101: res:960x540 hz:25 color_depth:8 scaling:on

  mode 102: res:960x540 hz:50 color_depth:4 scaling:on

  mode 103: res:960x540 hz:50 color_depth:8 scaling:on

  mode 104: res:720x450 hz:60 color_depth:4 scaling:on

  mode 105: res:720x450 hz:60 color_depth:8 scaling:on

  mode 106: res:840x525 hz:60 color_depth:4 scaling:on

  mode 107: res:840x525 hz:60 color_depth:8 scaling:on

  mode 108: res:800x450 hz:60 color_depth:4 scaling:on

  mode 109: res:800x450 hz:60 color_depth:8 scaling:on

  mode 110: res:960x600 hz:60 color_depth:4 scaling:on

  mode 111: res:960x600 hz:60 color_depth:8 scaling:on

  mode 112: res:1280x720 hz:60 color_depth:4 scaling:on

  mode 113: res:1280x720 hz:60 color_depth:8 scaling:on

  mode 114: res:1280x800 hz:60 color_depth:4 scaling:on

  mode 115: res:1280x800 hz:60 color_depth:8 scaling:on

  mode 116: res:720x450 hz:25 color_depth:4 scaling:on

  mode 117: res:720x450 hz:25 color_depth:8 scaling:on

  mode 118: res:840x525 hz:25 color_depth:4 scaling:on

  mode 119: res:840x525 hz:25 color_depth:8 scaling:on

  mode 120: res:800x450 hz:25 color_depth:4 scaling:on

  mode 121: res:800x450 hz:25 color_depth:8 scaling:on

  mode 122: res:960x600 hz:25 color_depth:4 scaling:on

  mode 123: res:960x600 hz:25 color_depth:8 scaling:on

  mode 124: res:1280x720 hz:25 color_depth:4 scaling:on

  mode 125: res:1280x720 hz:25 color_depth:8 scaling:on

  mode 126: res:1280x800 hz:25 color_depth:4 scaling:on

  mode 127: res:1280x800 hz:25 color_depth:8 scaling:on

  mode 128: res:720x450 hz:50 color_depth:4 scaling:on

  mode 129: res:720x450 hz:50 color_depth:8 scaling:on

  mode 130: res:840x525 hz:50 color_depth:4 scaling:on

  mode 131: res:840x525 hz:50 color_depth:8 scaling:on

  mode 132: res:800x450 hz:50 color_depth:4 scaling:on

  mode 133: res:800x450 hz:50 color_depth:8 scaling:on

  mode 134: res:960x600 hz:50 color_depth:4 scaling:on

  mode 135: res:960x600 hz:50 color_depth:8 scaling:on

  mode 136: res:1280x720 hz:50 color_depth:4 scaling:on

  mode 137: res:1280x720 hz:50 color_depth:8 scaling:on

  mode 138: res:1280x800 hz:50 color_depth:4 scaling:on

  mode 139: res:1280x800 hz:50 color_depth:8 scaling:on


Persistent screen id: 

Contextual screen id: 

Type: 11 inch external screen

Resolution: 480x640

Hertz: 75

Color Depth: 8

Scaling:off

Origin: (-480,0)

Rotation: 90

Resolutions for rotation 90:

  mode 0: res:768x1366 hz:60 color_depth:4

  mode 1: res:768x1366 hz:60 color_depth:8

  mode 2: res:768x1024 hz:75 color_depth:4

  mode 3: res:768x1024 hz:75 color_depth:8

  mode 4: res:768x1024 hz:60 color_depth:4

  mode 5: res:768x1024 hz:60 color_depth:8

  mode 6: res:600x800 hz:75 color_depth:4

  mode 7: res:600x800 hz:75 color_depth:8

  mode 8: res:600x800 hz:60 color_depth:4

  mode 9: res:600x800 hz:60 color_depth:8

  mode 10: res:480x640 hz:75 color_depth:4

  mode 11: res:480x640 hz:75 color_depth:8 <-- current mode

  mode 12: res:480x640 hz:60 color_depth:4

  mode 13: res:480x640 hz:60 color_depth:8

  mode 14: res:480x848 hz:60 color_depth:4

  mode 15: res:480x848 hz:60 color_depth:8

  mode 16: res:480x848 hz:75 color_depth:4

  mode 17: res:480x848 hz:75 color_depth:8

  mode 18: res:576x1024 hz:60 color_depth:4

  mode 19: res:576x1024 hz:60 color_depth:8

  mode 20: res:576x1024 hz:75 color_depth:4

  mode 21: res:576x1024 hz:75 color_depth:8

  mode 22: res:720x1280 hz:60 color_depth:4

  mode 23: res:720x1280 hz:60 color_depth:8

  mode 24: res:768x1360 hz:60 color_depth:4

  mode 25: res:768x1360 hz:60 color_depth:8

  mode 26: res:640x480 hz:75 color_depth:4

  mode 27: res:640x480 hz:75 color_depth:8

  mode 28: res:640x480 hz:60 color_depth:4

  mode 29: res:640x480 hz:60 color_depth:8

  mode 30: res:720x1280 hz:60 color_depth:4

  mode 31: res:720x1280 hz:60 color_depth:8

  mode 32: res:900x1440 hz:60 color_depth:4

  mode 33: res:900x1440 hz:60 color_depth:8

  mode 34: res:1050x1680 hz:60 color_depth:4

  mode 35: res:1050x1680 hz:60 color_depth:8

  mode 36: res:1080x1920 hz:60 color_depth:4

  mode 37: res:1080x1920 hz:60 color_depth:8

  mode 38: res:1200x1920 hz:60 color_depth:4

  mode 39: res:1200x1920 hz:60 color_depth:8

  mode 40: res:1440x2560 hz:60 color_depth:4

  mode 41: res:1440x2560 hz:60 color_depth:8

  mode 42: res:1600x2560 hz:60 color_depth:4

  mode 43: res:1600x2560 hz:60 color_depth:8

  mode 44: res:450x720 hz:60 color_depth:4 scaling:on

  mode 45: res:450x720 hz:60 color_depth:8 scaling:on

  mode 46: res:525x840 hz:60 color_depth:4 scaling:on

  mode 47: res:525x840 hz:60 color_depth:8 scaling:on

  mode 48: res:540x960 hz:60 color_depth:4 scaling:on

  mode 49: res:540x960 hz:60 color_depth:8 scaling:on

  mode 50: res:600x960 hz:60 color_depth:4 scaling:on

  mode 51: res:600x960 hz:60 color_depth:8 scaling:on

  mode 52: res:720x1280 hz:60 color_depth:4 scaling:on

  mode 53: res:720x1280 hz:60 color_depth:8 scaling:on

  mode 54: res:800x1280 hz:60 color_depth:4 scaling:on

  mode 55: res:800x1280 hz:60 color_depth:8 scaling:on

that's a lot to choose from, and it also clearly shows that macos messed up the size, resolution and hertz of my 2nd display. eventually i'm brave enough to place my displays as

$ ./displayplacer "id: res:2560x1440 hz:60 color_depth:8 scaling:off origin:(0,0) degree:0" "id: res:1080x1920 hz:60 color_depth:8 scaling:off origin:(-1080,-240) degree:270"

yes, none of them is native resolution.