use putIfAbsent to avoid races when creating a chain