Skip to content

Commit

Permalink
add signIn improvements && integrate redis api for lru on pr… (#656)
Browse files Browse the repository at this point in the history
* chore(): add signIn improvements && integrate redis api for lru on production

* chore(): please codefactor

* chore(): fix codefactor

* chore(): logging format
  • Loading branch information
kenshyx committed Feb 11, 2021
1 parent 8568635 commit c80b6a4
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 79 deletions.
15 changes: 7 additions & 8 deletions api/hub/src/datasources/comment.ts
Expand Up @@ -65,21 +65,20 @@ class CommentAPI extends DataSource {
postId: comment.postId,
content: comment.content.find(e => e.property === 'textContent')?.value,
});
queryCache.del(this.getAllCommentsCacheKey(commentData.postID));
await queryCache.del(this.getAllCommentsCacheKey(commentData.postID));
return commentID;
}

async getComments(postID: string, limit: number, offset: string) {
const db: Client = await getAppDB();
let comments;
const allCommentsCache = this.getAllCommentsCacheKey(postID);
if (queryCache.has(allCommentsCache)) {
comments = queryCache.get(allCommentsCache);
} else {
if (!(await queryCache.has(allCommentsCache))) {
const query = new Where('postId').eq(postID).orderByDesc('creationDate');
comments = await db.find<Comment>(this.dbID, this.collection, query);
queryCache.set(allCommentsCache, comments);
await queryCache.set(allCommentsCache, comments);
}
comments = await queryCache.get(allCommentsCache);
const offsetIndex = offset ? comments.findIndex(comment => comment._id === offset) : 0;
let endIndex = limit + offsetIndex;
if (comments.length <= endIndex) {
Expand All @@ -94,14 +93,14 @@ class CommentAPI extends DataSource {
const db: Client = await getAppDB();
let comment;
const commentCache = this.getCommentCacheKey(commentId);
if (queryCache.has(commentCache)) {
return Promise.resolve(queryCache.get(commentCache));
if (await queryCache.has(commentCache)) {
return queryCache.get(commentCache);
}
comment = await db.findByID<Comment>(this.dbID, this.collection, commentId);
if (!comment) {
return;
}
queryCache.set(commentCache, comment);
await queryCache.set(commentCache, comment);
return comment;
}
}
Expand Down
56 changes: 28 additions & 28 deletions api/hub/src/datasources/post.ts
Expand Up @@ -30,8 +30,8 @@ class PostAPI extends DataSource {
async getPost(id: string, pubKey?: string, stopIter = false) {
const db: Client = await getAppDB();
const cacheKey = this.getPostCacheKey(id);
if (queryCache.has(cacheKey)) {
return Promise.resolve(queryCache.get(cacheKey));
if (await queryCache.has(cacheKey)) {
return queryCache.get(cacheKey);
}
const post = await db.findByID<PostItem>(this.dbID, this.collection, id);
if (!post) {
Expand All @@ -40,44 +40,42 @@ class PostAPI extends DataSource {
const quotedBy = post?.metaData
?.filter(item => item.property === this.quotedByPost)
?.map(item => item.value);
Object.assign(post, { quotedBy });
if (post?.quotes?.length && !stopIter) {
post.quotes = await Promise.all(
post.quotes.map(postID => this.getPost(postID, pubKey, true)),
const result = JSON.parse(JSON.stringify(Object.assign({}, post, { quotedBy })));
if (result?.quotes?.length && !stopIter) {
result.quotes = await Promise.all(
result.quotes.map(postID => this.getPost(postID, pubKey, true)),
);
}
queryCache.set(cacheKey, post);
return post;
await queryCache.set(cacheKey, result);
return result;
}
async getPosts(limit: number, offset: string, pubKey?: string) {
let posts;
const db: Client = await getAppDB();
if (queryCache.has(this.allPostsCache)) {
posts = queryCache.get(this.allPostsCache);
} else {
if (!(await queryCache.has(this.allPostsCache))) {
posts = await db.find<PostItem>(this.dbID, this.collection, {
sort: { desc: true, fieldPath: 'creationDate' },
});
for (const post of posts) {
if (post?.quotes?.length) {
post.quotes = await Promise.all(post.quotes.map(postID => this.getPost(postID, pubKey)));
}
const quotedBy = post?.metaData
?.filter(item => item.property === this.quotedByPost)
?.map(item => item.value);
Object.assign(post, { quotedBy });
}
queryCache.set(this.allPostsCache, posts);
await queryCache.set(
this.allPostsCache,
posts.map(p => p._id),
);
}
posts = await queryCache.get(this.allPostsCache);
const fetchedPosts = [];

const offsetIndex = offset ? posts.findIndex(postItem => postItem._id === offset) : 0;
const offsetIndex = offset ? posts.findIndex(postItem => postItem === offset) : 0;
let endIndex = limit + offsetIndex;
if (posts.length <= endIndex) {
endIndex = undefined;
}
const results = posts.slice(offsetIndex, endIndex);
const nextIndex = endIndex ? posts[endIndex]._id : null;
return { results: results, nextIndex: nextIndex, total: posts.length };
const nextIndex = endIndex ? posts[endIndex] : null;
for (const postID of results) {
const post = await this.getPost(postID, pubKey);
fetchedPosts.push(post);
}
return { results: fetchedPosts, nextIndex: nextIndex, total: posts.length };
}
async createPost(
author: string,
Expand Down Expand Up @@ -113,11 +111,13 @@ class PostAPI extends DataSource {
],
};
logger.info('saving a new post:', post);
queryCache.del(this.allPostsCache);
const postID = await db.create(this.dbID, this.collection, [post]);
logger.info('created a new post:', postID);
const currentPosts = await queryCache.get(this.allPostsCache);
if (currentPosts.length) {
currentPosts.unshift(postID[0]);
}
await this.addQuotes(post.quotes, postID[0]);
queryCache.del(this.allPostsCache);
if (post.mentions && post.mentions.length) {
await this.triggerMentions(post.mentions, postID[0], post.author);
}
Expand All @@ -132,7 +132,7 @@ class PostAPI extends DataSource {
content: post.content.find(e => e.property === 'textContent')?.value,
title: post.title,
})
.then(_ => logger.info('indexed post:', postID[0]))
.then(_ => logger.info('indexed post:', postID))
// tslint:disable-next-line:no-console
.catch(e => logger.error(e));
return postID;
Expand Down Expand Up @@ -179,7 +179,7 @@ class PostAPI extends DataSource {
if (updatePosts.length) {
await db.save(this.dbID, this.collection, updatePosts);
for (const post of updatePosts) {
queryCache.del(this.getPostCacheKey(post._id));
await queryCache.del(this.getPostCacheKey(post._id));
}
}
updatePosts.length = 0;
Expand Down
30 changes: 15 additions & 15 deletions api/hub/src/datasources/profile.ts
Expand Up @@ -23,16 +23,16 @@ class ProfileAPI extends DataSource {
const db: Client = await getAppDB();
let pubKey;
const key = this.getCacheKey(`:eth:${ethAddress}`);
if (!queryCache.has(key)) {
if (!(await queryCache.has(key))) {
const query = new Where('ethAddress').eq(ethAddress);
const profilesFound = await db.find<Profile>(this.dbID, this.collection, query);
if (!profilesFound.length) {
return;
}
pubKey = profilesFound[0].pubKey;
queryCache.set(key, pubKey);
await queryCache.set(key, pubKey);
} else {
pubKey = queryCache.get(key);
pubKey = await queryCache.get(key);
}
return await this.resolveProfile(pubKey);
}
Expand All @@ -42,8 +42,8 @@ class ProfileAPI extends DataSource {
}
async resolveProfile(pubKey: string, noCache: boolean = false) {
const cacheKey = this.getCacheKey(pubKey);
if (queryCache.has(cacheKey) && !noCache) {
return Promise.resolve(queryCache.get(cacheKey));
if ((await queryCache.has(cacheKey)) && !noCache) {
return queryCache.get(cacheKey);
}
const db: Client = await getAppDB();
const query = new Where('pubKey').eq(pubKey);
Expand All @@ -54,7 +54,7 @@ class ProfileAPI extends DataSource {
if (profilesFound.length) {
const extractedFields = ['name', 'description', 'avatar', 'coverImage'];
const q = profilesFound[0].default.filter(p => extractedFields.includes(p.property));
const returnedObj = Object.assign({}, profilesFound[0]);
const returnedObj = JSON.parse(JSON.stringify(profilesFound[0]));
for (const provider of q) {
Object.assign(returnedObj, { [provider.property]: provider.value });
}
Expand All @@ -68,7 +68,7 @@ class ProfileAPI extends DataSource {
totalFollowers: profilesFound[0]?.followers?.length || 0,
totalFollowing: profilesFound[0]?.following?.length || 0,
});
queryCache.set(cacheKey, returnedObj);
await queryCache.set(cacheKey, returnedObj);
return returnedObj;
}
return;
Expand All @@ -93,7 +93,7 @@ class ProfileAPI extends DataSource {
}
}
await db.save(this.dbID, this.collection, [profile]);
queryCache.del(this.getCacheKey(pubKey));
await queryCache.del(this.getCacheKey(pubKey));
return profile._id;
}
async makeDefaultProvider(pubKey: string, data: DataProvider[]) {
Expand All @@ -113,7 +113,7 @@ class ProfileAPI extends DataSource {
}
}
await db.save(this.dbID, this.collection, [profile]);
queryCache.del(this.getCacheKey(pubKey));
await queryCache.del(this.getCacheKey(pubKey));
searchIndex
.saveObject({
objectID: profile._id,
Expand Down Expand Up @@ -148,7 +148,7 @@ class ProfileAPI extends DataSource {

profile.userName = name;
await db.save(this.dbID, this.collection, [profile]);
queryCache.del(this.getCacheKey(pubKey));
await queryCache.del(this.getCacheKey(pubKey));
searchIndex
.saveObject({
objectID: profile._id,
Expand Down Expand Up @@ -178,8 +178,8 @@ class ProfileAPI extends DataSource {
profile1.following.unshift(profile.pubKey);
profile.followers.unshift(profile1.pubKey);
await db.save(this.dbID, this.collection, [profile, profile1]);
queryCache.del(this.getCacheKey(profile.pubKey));
queryCache.del(this.getCacheKey(profile1.pubKey));
await queryCache.del(this.getCacheKey(profile.pubKey));
await queryCache.del(this.getCacheKey(profile1.pubKey));
const notification = {
property: 'NEW_FOLLOWER',
provider: 'awf.graphql.profile.api',
Expand All @@ -206,8 +206,8 @@ class ProfileAPI extends DataSource {
profile1.following.splice(exists, 1);
profile.followers.splice(exists1, 1);
await db.save(this.dbID, this.collection, [profile, profile1]);
queryCache.del(this.getCacheKey(profile.pubKey));
queryCache.del(this.getCacheKey(profile1.pubKey));
await queryCache.del(this.getCacheKey(profile.pubKey));
await queryCache.del(this.getCacheKey(profile1.pubKey));
return true;
}

Expand All @@ -229,7 +229,7 @@ class ProfileAPI extends DataSource {
}

await db.save(this.dbID, this.collection, [profile]);
queryCache.del(this.getCacheKey(pubKey));
await queryCache.del(this.getCacheKey(pubKey));
return profile._id;
}

Expand Down
10 changes: 5 additions & 5 deletions api/hub/src/datasources/tag.ts
Expand Up @@ -61,13 +61,13 @@ class TagAPI extends DataSource {
async getTags(limit: number, offset: string) {
let tag: Tag[];
const db: Client = await getAppDB();
if (queryCache.has(this.collection)) {
tag = queryCache.get(this.collection);
if (await queryCache.has(this.collection)) {
tag = await queryCache.get(this.collection);
} else {
tag = await db.find<Tag>(this.dbID, this.collection, {
sort: { desc: true, fieldPath: 'creationDate' },
});
queryCache.set(this.collection, tag);
await queryCache.set(this.collection, tag);
}
const offsetIndex = offset ? tag.findIndex(tagItem => tagItem._id === offset) : 0;
let endIndex = limit + offsetIndex;
Expand All @@ -82,7 +82,7 @@ class TagAPI extends DataSource {
async indexPost(postsCollection: string, postID: string, tagName: string) {
const db: Client = await getAppDB();
const postExists = await db.has(this.dbID, postsCollection, [postID]);
logger.info('indexing tags for post:', postID, tagName);
logger.info(`indexing tags for post: ${postID} -- ${tagName}`);
if (!postExists) {
return Promise.reject(`postID: ${postID} was not found`);
}
Expand Down Expand Up @@ -150,7 +150,7 @@ class TagAPI extends DataSource {
.then(_ => _)
// tslint:disable-next-line:no-console
.catch(e => console.error(e));
queryCache.del(this.collection);
await queryCache.del(this.collection);
return tagID[0];
}
}
Expand Down
7 changes: 3 additions & 4 deletions api/hub/src/index.ts
Expand Up @@ -5,8 +5,7 @@ import json from 'koa-json';
import bodyParser from 'koa-bodyparser';
import webSockify from 'koa-websocket';
import cors from '@koa/cors';
import { ApolloServer, gql } from 'apollo-server-koa';
import { RedisCache } from 'apollo-server-cache-redis';
import { ApolloServer } from 'apollo-server-koa';
import typeDefs from './schema';

import dotenv from 'dotenv';
Expand All @@ -15,7 +14,7 @@ dotenv.config();
import wss from './wss';
import api from './api';
import ProfileAPI from './datasources/profile';
import { contextCache } from './storage/cache';
import { contextCache, redisCache } from './storage/cache';
import TagAPI from './datasources/tag';
import PostAPI from './datasources/post';
import CommentAPI from './datasources/comment';
Expand Down Expand Up @@ -65,7 +64,7 @@ const server = new ApolloServer({
Query: query,
Mutation: mutations,
},
cache: process.env.NODE_ENV === 'production' && new RedisCache(process.env.REDIS_CONNECTION),
cache: redisCache,
dataSources: () => ({
profileAPI: new ProfileAPI({ dbID, collection: 'Profiles' }),
tagsAPI: new TagAPI({ dbID, collection: 'Tags' }),
Expand Down
19 changes: 12 additions & 7 deletions api/hub/src/resolvers/mutations.ts
@@ -1,29 +1,30 @@
import { commentsStats, postsStats, statsProvider } from './constants';
import { queryCache } from '../storage/cache';

const mutations = {
addProfileProvider: async (_, { data }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.addProfileProvider(user.pubKey, data);
return dataSources.profileAPI.addProfileProvider(user.pubKey, data);
},
makeDefaultProvider: async (_, { data }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.makeDefaultProvider(user.pubKey, data);
return dataSources.profileAPI.makeDefaultProvider(user.pubKey, data);
},
registerUserName: async (_, { name }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.registerUserName(user.pubKey, name);
return dataSources.profileAPI.registerUserName(user.pubKey, name);
},
createTag: async (_, { name }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.tagsAPI.addTag(name);
return dataSources.tagsAPI.addTag(name);
},
createPost: async (_, { content, post }, { dataSources, user }) => {
if (!user) {
Expand Down Expand Up @@ -59,25 +60,27 @@ const mutations = {
await dataSources.tagsAPI.indexPost('Posts', postID[0], tag);
}
}
const userIDCache = dataSources.profileAPI.getCacheKey(user.pubKey);
await queryCache.del(userIDCache);
return postID[0];
},
follow: async (_, { ethAddress }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.followProfile(user.pubKey, ethAddress);
return dataSources.profileAPI.followProfile(user.pubKey, ethAddress);
},
unFollow: async (_, { ethAddress }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.unFollowProfile(user.pubKey, ethAddress);
return dataSources.profileAPI.unFollowProfile(user.pubKey, ethAddress);
},
saveMetaData: async (_, { data }, { dataSources, user }) => {
if (!user) {
return Promise.reject('Must be authenticated!');
}
return await dataSources.profileAPI.saveMetadata(user.pubKey, data);
return dataSources.profileAPI.saveMetadata(user.pubKey, data);
},
addComment: async (_, { content, comment }, { dataSources, user }) => {
if (!user) {
Expand Down Expand Up @@ -116,6 +119,8 @@ const mutations = {
await dataSources.tagsAPI.indexComment('Comments', commentID[0], tag);
}
}
const postIDCache = dataSources.postsAPI.getPostCacheKey(comment.postID);
await queryCache.del(postIDCache);
return commentID[0];
},
};
Expand Down

0 comments on commit c80b6a4

Please sign in to comment.