Skip to content

Commit

Permalink
comment
Browse files Browse the repository at this point in the history
  • Loading branch information
callicoder committed Nov 17, 2018
1 parent ae20007 commit a81feca
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 1 deletion.
4 changes: 3 additions & 1 deletion react-social/src/user/login/Login.js
Expand Up @@ -10,6 +10,8 @@ import Alert from 'react-s-alert';

class Login extends Component {
componentDidMount() {
// If the OAuth2 login encounters an error, the user is redirected to the /login page with an error.
// Here we display the error and then remove the error query parameter from the location.
if(this.props.location.state && this.props.location.state.error) {
setTimeout(() => {
Alert.error(this.props.location.state.error, {
Expand Down Expand Up @@ -121,4 +123,4 @@ class LoginForm extends Component {
}
}

export default Login
export default Login
@@ -0,0 +1,110 @@
package com.example.springsocial.controller;


import java.net.NetworkInterface;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.Enumeration;

/**
* Distributed Sequence Generator.
* Inspired by Twitter snowflake: https://github.com/twitter/snowflake/tree/snowflake-2010
*
* This class should be used as a Singleton.
* Make sure that you create and reuse a Single instance of SequenceGenerator per machine in your distributed system cluster.
*/
public class SequenceGenerator {
private static final int TOTAL_BITS = 64;
private static final int EPOCH_BITS = 42;
private static final int MACHINE_ID_BITS = 10;
private static final int SEQUENCE_BITS = 12;

private static final int maxMachineId = (int)(Math.pow(2, MACHINE_ID_BITS) - 1);
private static final int maxSequence = (int)(Math.pow(2, SEQUENCE_BITS) - 1);

// Custom Epoch (January 1, 2015 Midnight UTC = 2015-01-01T00:00:00Z)
private static final long CUSTOM_EPOCH = 1420070400000L;

private final int machineId;

private long lastTimestamp = -1L;
private long sequence = 0L;

// Create Snowflake with a machineId
public SequenceGenerator(int machineId) {
if(machineId < 0 || machineId > maxMachineId) {
throw new IllegalArgumentException(String.format("MachineId must be between %d and %d", 0, maxMachineId));
}
this.machineId = machineId;
}

// Let Snowflake generate a machineId
public SequenceGenerator() {
this.machineId = createMachineId();
}


public long nextId() {
long currentTimestamp = timestamp();

synchronized (this) {
if(currentTimestamp < lastTimestamp) {
throw new IllegalStateException("Invalid System Clock!");
}

if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & maxSequence;
if(sequence == 0) {
// Sequence Exhausted, wait till next millisecond.
currentTimestamp = waitNextMillis(currentTimestamp);
}
} else {
// reset sequence for next millisecond
sequence = 0;
}

lastTimestamp = currentTimestamp;
}

long id = currentTimestamp << (TOTAL_BITS - EPOCH_BITS);
id |= (machineId << (TOTAL_BITS - EPOCH_BITS - MACHINE_ID_BITS));
id |= sequence;
return id;
}


// Get current timestamp in milliseconds, adjust for the custom epoch.
private static long timestamp() {
return Instant.now().toEpochMilli() - CUSTOM_EPOCH;
}

// Block and wait till next millisecond
private long waitNextMillis(long currentTimestamp) {
while (currentTimestamp == lastTimestamp) {
currentTimestamp = timestamp();
}
return currentTimestamp;
}

private int createMachineId() {
int machineId;
try {
StringBuilder sb = new StringBuilder();
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
byte[] mac = networkInterface.getHardwareAddress();
if (mac != null) {
for(int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X", mac[i]));
}
}
}
machineId = sb.toString().hashCode();
} catch (Exception ex) {
machineId = (new SecureRandom().nextInt());
}
machineId = machineId & maxMachineId;
return machineId;
}
}

0 comments on commit a81feca

Please sign in to comment.