Skip to content

Commit

Permalink
feat: add impressions worker (#3972)
Browse files Browse the repository at this point in the history
  • Loading branch information
bigint authored Nov 8, 2023
2 parents 51d11b3 + ac792d4 commit 71473bb
Show file tree
Hide file tree
Showing 25 changed files with 255 additions and 956 deletions.
34 changes: 14 additions & 20 deletions apps/web/public/impressions.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
const postsEndpoint = 'https://ens.hey.xyz';
const postsVisibilityInterval = 5000;
let visiblePostsSet = new Set();
const impressionsEndpoint = 'https://impressions.hey.xyz/ingest';
const publicationsVisibilityInterval = 5000;
let visiblePublicationsSet = new Set();

function sendVisiblePostsToServer() {
const postsToSend = Array.from(visiblePostsSet);
function sendVisiblePublicationsToServer() {
const publicationsToSend = Array.from(visiblePublicationsSet);

if (postsToSend.length > 0) {
visiblePostsSet.clear();
fetch(postsEndpoint, {
if (publicationsToSend.length > 0) {
visiblePublicationsSet.clear();
fetch(impressionsEndpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ visiblePosts: postsToSend }),
body: JSON.stringify({ ids: publicationsToSend }),
keepalive: true
})
.then((response) => {
if (!response.ok) {
console.error('Failed to send visible posts:', response);
}
})
.catch((error) => {
console.error('Error sending visible posts:', error);
});
.then(() => {})
.catch(() => {});
}
}

setInterval(sendVisiblePostsToServer, postsVisibilityInterval);
setInterval(sendVisiblePublicationsToServer, publicationsVisibilityInterval);

self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'POST_VISIBLE') {
visiblePostsSet.add(event.data.postId);
if (event.data && event.data.type === 'PUBLICATION_VISIBLE') {
visiblePublicationsSet.add(event.data.id);
}
});
35 changes: 1 addition & 34 deletions apps/web/src/components/Common/Providers/LeafwatchProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,18 @@
import { IMPRESSIONS_SERVICE_URL, IS_MAINNET } from '@hey/data/constants';
import { type FC } from 'react';
import useWebSocket from 'react-use-websocket';
import { useLeafwatchPersistStore } from 'src/store/useLeafwatchPersistStore';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce, useInterval, useUpdateEffect } from 'usehooks-ts';
import { useEffectOnce } from 'usehooks-ts';
import { v4 as uuid } from 'uuid';

const LeafwatchProvider: FC = () => {
const viewerId = useLeafwatchPersistStore((state) => state.viewerId);
const setViewerId = useLeafwatchPersistStore((state) => state.setViewerId);
const viewedPublication = useLeafwatchStore(
(state) => state.viewedPublication
);

const { sendJsonMessage, readyState } = useWebSocket(
IMPRESSIONS_SERVICE_URL,
{
reconnectAttempts: 5,
reconnectInterval: 5000,
shouldReconnect: () => true
}
);

useEffectOnce(() => {
sendJsonMessage({ type: 'connection_init' });
if (!viewerId) {
setViewerId(uuid());
}
});

useInterval(() => {
sendJsonMessage({ type: 'connection_init' });
}, 10000);

useUpdateEffect(() => {
if (readyState === 1 && viewedPublication && IS_MAINNET) {
sendJsonMessage({
id: '1',
type: 'start',
payload: JSON.stringify({
viewer_id: viewerId,
publication_id: viewedPublication
})
});
}
}, [readyState, viewedPublication]);

return null;
};

Expand Down
12 changes: 5 additions & 7 deletions apps/web/src/components/Notification/Type/ActedNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { isMirrorPublication } from '@hey/lib/publicationHelpers';
import Link from 'next/link';
import plur from 'plur';
import type { FC } from 'react';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce } from 'usehooks-ts';

import AggregatedNotificationTitle from '../AggregatedNotificationTitle';
Expand All @@ -17,10 +16,6 @@ interface ActedNotificationProps {
}

const ActedNotification: FC<ActedNotificationProps> = ({ notification }) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const publication = notification?.publication;
const targetPublication = isMirrorPublication(publication)
? publication.mirrorOn
Expand All @@ -38,8 +33,11 @@ const ActedNotification: FC<ActedNotificationProps> = ({ notification }) => {
const type = notification?.publication.__typename;

useEffectOnce(() => {
if (notification?.publication) {
setViewedPublication(notification?.publication.id);
if (notification?.publication.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'PUBLICATION_VISIBLE',
id: notification.publication.id
});
}
});

Expand Down
12 changes: 5 additions & 7 deletions apps/web/src/components/Notification/Type/MirrorNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import getPublicationData from '@hey/lib/getPublicationData';
import Link from 'next/link';
import plur from 'plur';
import type { FC } from 'react';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce } from 'usehooks-ts';

import AggregatedNotificationTitle from '../AggregatedNotificationTitle';
Expand All @@ -16,10 +15,6 @@ interface MirrorNotificationProps {
}

const MirrorNotification: FC<MirrorNotificationProps> = ({ notification }) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const metadata = notification?.publication.metadata;
const filteredContent = getPublicationData(metadata)?.content || '';
const mirrors = notification?.mirrors;
Expand All @@ -33,8 +28,11 @@ const MirrorNotification: FC<MirrorNotificationProps> = ({ notification }) => {
const type = notification?.publication.__typename;

useEffectOnce(() => {
if (notification?.publication) {
setViewedPublication(notification?.publication.id);
if (notification?.publication.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'PUBLICATION_VISIBLE',
id: notification.publication.id
});
}
});

Expand Down
12 changes: 5 additions & 7 deletions apps/web/src/components/Notification/Type/QuoteNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { QuoteNotification } from '@hey/lens';
import getPublicationData from '@hey/lib/getPublicationData';
import Link from 'next/link';
import type { FC } from 'react';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce } from 'usehooks-ts';

import AggregatedNotificationTitle from '../AggregatedNotificationTitle';
Expand All @@ -15,10 +14,6 @@ interface QuoteNotificationProps {
}

const QuoteNotification: FC<QuoteNotificationProps> = ({ notification }) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const metadata = notification?.quote.metadata;
const filteredContent = getPublicationData(metadata)?.content || '';
const firstProfile = notification.quote.by;
Expand All @@ -27,8 +22,11 @@ const QuoteNotification: FC<QuoteNotificationProps> = ({ notification }) => {
const type = notification.quote.quoteOn.__typename;

useEffectOnce(() => {
if (notification?.quote) {
setViewedPublication(notification?.quote.id);
if (notification?.quote.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'PUBLICATION_VISIBLE',
id: notification.quote.id
});
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import getPublicationData from '@hey/lib/getPublicationData';
import Link from 'next/link';
import plur from 'plur';
import type { FC } from 'react';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce } from 'usehooks-ts';

import AggregatedNotificationTitle from '../AggregatedNotificationTitle';
Expand All @@ -18,10 +17,6 @@ interface ReactionNotificationProps {
const ReactionNotification: FC<ReactionNotificationProps> = ({
notification
}) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const metadata = notification?.publication.metadata;
const filteredContent = getPublicationData(metadata)?.content || '';
const reactions = notification?.reactions;
Expand All @@ -35,8 +30,11 @@ const ReactionNotification: FC<ReactionNotificationProps> = ({
const type = notification?.publication.__typename;

useEffectOnce(() => {
if (notification?.publication) {
setViewedPublication(notification?.publication.id);
if (notification?.publication.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'PUBLICATION_VISIBLE',
id: notification.publication.id
});
}
});

Expand Down
12 changes: 5 additions & 7 deletions apps/web/src/components/Publication/FullPublication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import getAppName from '@hey/lib/getAppName';
import { isMirrorPublication } from '@hey/lib/publicationHelpers';
import { formatDate } from '@lib/formatTime';
import { type FC } from 'react';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';
import { useEffectOnce } from 'usehooks-ts';

import PublicationActions from './Actions';
Expand All @@ -19,19 +18,18 @@ interface FullPublicationProps {
}

const FullPublication: FC<FullPublicationProps> = ({ publication }) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const targetPublication = isMirrorPublication(publication)
? publication?.mirrorOn
: publication;

const { metadata, createdAt } = targetPublication;

useEffectOnce(() => {
if (targetPublication.id) {
setViewedPublication(targetPublication.id);
if (targetPublication.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'PUBLICATION_VISIBLE',
id: targetPublication.id
});
}
});

Expand Down
9 changes: 2 additions & 7 deletions apps/web/src/components/Publication/SinglePublication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { isMirrorPublication } from '@hey/lib/publicationHelpers';
import cn from '@hey/ui/cn';
import { type FC } from 'react';
import { useInView } from 'react-cool-inview';
import { useLeafwatchStore } from 'src/store/useLeafwatchStore';

import PublicationActions from './Actions';
import ModAction from './Actions/ModAction';
Expand Down Expand Up @@ -38,10 +37,6 @@ const SinglePublication: FC<SinglePublicationProps> = ({
isFirst = false,
isLast = false
}) => {
const setViewedPublication = useLeafwatchStore(
(state) => state.setViewedPublication
);

const firstComment = feedItem?.comments?.[0];
const rootPublication = feedItem
? firstComment
Expand All @@ -60,8 +55,8 @@ const SinglePublication: FC<SinglePublicationProps> = ({

if (rootPublication.id && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'POST_VISIBLE',
postId: rootPublication.id
type: 'PUBLICATION_VISIBLE',
id: rootPublication.id
});
}
}
Expand Down
12 changes: 0 additions & 12 deletions apps/web/src/store/useLeafwatchStore.ts

This file was deleted.

2 changes: 1 addition & 1 deletion docs/ports.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ The following ports are exposed by the repository
| ---- | -------------------------- | --------------------- | ------------------------------ |
| 4783 | Web app | http://localhost:4783 | https://hey.xyz |
| 4784 | Prerender app | http://localhost:4784 | https://prerender.hey.xyz |
| 5001 | Impressions service | http://localhost:5001 | https://impressions.hey.xyz |
| 8082 | STS token generator worker | http://localhost:8082 | https://sts.hey.xyz |
| 8083 | Metadata worker | http://localhost:8083 | https://metadata.hey.xyz |
| 8084 | Snapshot relay worker | http://localhost:8084 | https://snapshot-relay.hey.xyz |
Expand All @@ -20,3 +19,4 @@ The following ports are exposed by the repository
| 8092 | NFT worker | http://localhost:8092 | https://nft.hey.xyz |
| 8093 | Staff Picks worker | http://localhost:8093 | https://staff-picks.hey.xyz |
| 8094 | Live worker | http://localhost:8094 | https://live.hey.xyz |
| 8094 | Impressions worker | http://localhost:8094 | https://impressions.hey.xyz |
File renamed without changes.
3 changes: 1 addition & 2 deletions packages/workers/impressions/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ module.exports = {
extends: [require.resolve('@hey/config/eslint/base.js')],
rules: {
'import/no-anonymous-default-export': 'off'
},
ignorePatterns: ['**/dist/**/*']
}
};
1 change: 0 additions & 1 deletion packages/workers/impressions/.gitignore

This file was deleted.

15 changes: 15 additions & 0 deletions packages/workers/impressions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Impressions worker

## Clickhouse Schema

```sql
CREATE TABLE impressions (
id UUID,
viewer_id String,
publication_id String,
viewed_at DateTime64(3, 'UTC') DEFAULT now64(3)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(viewed_at)
ORDER BY (viewer_id, publication_id, viewed_at)
SETTINGS index_granularity = 8192;
```
Loading

2 comments on commit 71473bb

@vercel
Copy link

@vercel vercel bot commented on 71473bb Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

prerender – ./apps/prerender

prerender-heyxyz.vercel.app
prerender-git-main-heyxyz.vercel.app
prerender.hey.xyz

@vercel
Copy link

@vercel vercel bot commented on 71473bb Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

web – ./apps/web

web-git-main-heyxyz.vercel.app
heyxyz.vercel.app
hey.xyz
web-heyxyz.vercel.app

Please sign in to comment.