Skip to content

Commit a81feca

Browse files
committedNov 17, 2018
comment
1 parent ae20007 commit a81feca

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed
 

‎react-social/src/user/#/#.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import Alert from 'react-s-alert';
1010

1111
class Login extends Component {
1212
componentDidMount() {
13+
// If the OAuth2 login encounters an error, the user is redirected to the /# page with an error.
14+
// Here we display the error and then remove the error query parameter from the location.
1315
if(this.props.location.state && this.props.location.state.error) {
1416
setTimeout(() => {
1517
Alert.error(this.props.location.state.error, {
@@ -121,4 +123,4 @@ class LoginForm extends Component {
121123
}
122124
}
123125

124-
export default Login
126+
export default Login
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.example.springsocial.controller;
2+
3+
4+
import java.net.NetworkInterface;
5+
import java.security.SecureRandom;
6+
import java.time.Instant;
7+
import java.util.Enumeration;
8+
9+
/**
10+
* Distributed Sequence Generator.
11+
* Inspired by Twitter snowflake: https://github.com/twitter/snowflake/tree/snowflake-2010
12+
*
13+
* This class should be used as a Singleton.
14+
* Make sure that you create and reuse a Single instance of SequenceGenerator per machine in your distributed system cluster.
15+
*/
16+
public class SequenceGenerator {
17+
private static final int TOTAL_BITS = 64;
18+
private static final int EPOCH_BITS = 42;
19+
private static final int MACHINE_ID_BITS = 10;
20+
private static final int SEQUENCE_BITS = 12;
21+
22+
private static final int maxMachineId = (int)(Math.pow(2, MACHINE_ID_BITS) - 1);
23+
private static final int maxSequence = (int)(Math.pow(2, SEQUENCE_BITS) - 1);
24+
25+
// Custom Epoch (January 1, 2015 Midnight UTC = 2015-01-01T00:00:00Z)
26+
private static final long CUSTOM_EPOCH = 1420070400000L;
27+
28+
private final int machineId;
29+
30+
private long lastTimestamp = -1L;
31+
private long sequence = 0L;
32+
33+
// Create Snowflake with a machineId
34+
public SequenceGenerator(int machineId) {
35+
if(machineId < 0 || machineId > maxMachineId) {
36+
throw new IllegalArgumentException(String.format("MachineId must be between %d and %d", 0, maxMachineId));
37+
}
38+
this.machineId = machineId;
39+
}
40+
41+
// Let Snowflake generate a machineId
42+
public SequenceGenerator() {
43+
this.machineId = createMachineId();
44+
}
45+
46+
47+
public long nextId() {
48+
long currentTimestamp = timestamp();
49+
50+
synchronized (this) {
51+
if(currentTimestamp < lastTimestamp) {
52+
throw new IllegalStateException("Invalid System Clock!");
53+
}
54+
55+
if (currentTimestamp == lastTimestamp) {
56+
sequence = (sequence + 1) & maxSequence;
57+
if(sequence == 0) {
58+
// Sequence Exhausted, wait till next millisecond.
59+
currentTimestamp = waitNextMillis(currentTimestamp);
60+
}
61+
} else {
62+
// reset sequence for next millisecond
63+
sequence = 0;
64+
}
65+
66+
lastTimestamp = currentTimestamp;
67+
}
68+
69+
long id = currentTimestamp << (TOTAL_BITS - EPOCH_BITS);
70+
id |= (machineId << (TOTAL_BITS - EPOCH_BITS - MACHINE_ID_BITS));
71+
id |= sequence;
72+
return id;
73+
}
74+
75+
76+
// Get current timestamp in milliseconds, adjust for the custom epoch.
77+
private static long timestamp() {
78+
return Instant.now().toEpochMilli() - CUSTOM_EPOCH;
79+
}
80+
81+
// Block and wait till next millisecond
82+
private long waitNextMillis(long currentTimestamp) {
83+
while (currentTimestamp == lastTimestamp) {
84+
currentTimestamp = timestamp();
85+
}
86+
return currentTimestamp;
87+
}
88+
89+
private int createMachineId() {
90+
int machineId;
91+
try {
92+
StringBuilder sb = new StringBuilder();
93+
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
94+
while (networkInterfaces.hasMoreElements()) {
95+
NetworkInterface networkInterface = networkInterfaces.nextElement();
96+
byte[] mac = networkInterface.getHardwareAddress();
97+
if (mac != null) {
98+
for(int i = 0; i < mac.length; i++) {
99+
sb.append(String.format("%02X", mac[i]));
100+
}
101+
}
102+
}
103+
machineId = sb.toString().hashCode();
104+
} catch (Exception ex) {
105+
machineId = (new SecureRandom().nextInt());
106+
}
107+
machineId = machineId & maxMachineId;
108+
return machineId;
109+
}
110+
}

0 commit comments

Comments
 (0)