Je serais reconnaissant si quelqu'un peut m'aider à répondre aux questions au code suivant
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
    Some server side code
*/
 
const updateExceededDays = params => {
    const concurrency = 50;
    return Promise.resolve(params)
        .then(params => utils.validateParameters(params, {
            req: {type: ['object', 'null']}, // allow null because it might be called from within the trial day cron job
            parentTrx: {type: 'function'},
        }))
        .then(params => PFC.props({
            organizationIds: () => {
                return knex('organizations AS o')
                    .transacting(params.parentTrx)
                    .select(['o.id'])
                    .innerJoin('accesses AS a', 'a.organizationId', 'o.id')
                    .innerJoin('users AS u', 'u.id', 'a.userId')
                    .where('a.accessType', constants.accessTypes.ORGANIZATION)
                    .where('a.isOwner', true)
                    .whereNull('a.deprecated_at')
                    .whereNull('u.deprecated_at')
                    .whereRaw('o.exceeded_days_updated_at::date < current_date')
                    .whereNot('o.escalationLevel', constants.escalationLevels.NONE)
                    .whereNotNull('o.escalationLevel')
                    .whereNull('o.deprecated_at')
                    .then(rows => _.map(rows, 'id'));
            },
            updateExceededDays: ['organizationIds', ({organizationIds}) => {
                if (_.isEmpty(organizationIds)) {
                    return null;
                }
                return knex('organizations')
                    .transacting(params.parentTrx)
                    .update({
                        // Note: knex.increment does not play well with knex.update
                        // <a href="https://github.com/tgriesser/knex/issues/269" target="_blank">https://github.com/tgriesser/knex/issues/269</a>
                        exceededDays: knex.raw('"exceededDays" + 1'),
                        exceeded_days_updated_at: 'now',
                        updated_at: 'now',
                    })
                    .whereIn('id', organizationIds)
                    .return(null);
            }],
            updatedOrganizations: ['organizationIds', 'updateExceededDays', ({organizationIds}) => {
                // We use the trial days to determine the escalation level
                return Promise.map(organizationIds, organizationId => OrganizationController.updateCachedFieldsOfOrganization({
                    req: params.req,
                    parentTrx: params.parentTrx,
                    organizationId,
                    skipDataAggregation: true
                }), {concurrency});
            }],
            sendOutStatusEmails: ['updatedOrganizations', ({updatedOrganizations}) => {
                return Promise.map(updatedOrganizations, organization => {
                    // Inform the user at the start and end of the trial phase
                    if (organization.exceededDays === 1 ||
                        organization.exceededDays === constants.maxExceededDays + 1) {
                        return OrganizationController
                            .sendOutOrganizationStatusEmail({
                                req: params.req,
                                parentTrx: params.parentTrx,
                                organization
                            })
                            .catch(err => {
                                // We are ignoring errors here in order to at least inform the other users
                                _strucd.log.error(`updateExceededDays Cronjob: Error when sending out organization status email. OrganizationId: ${organization.id} Error message: ${err.message}`);
                            });
                    }
                }, {concurrency});
            }]
        }))
        .return(null);
};
 
/*
    Questions:
    * What do you think PFC.props is doing?
    * What is the concurrency variable good for?
    * sendOutStatusEmails ignores errors (except for logging them).
      Let's say your task was to make sure the whole function fails as soon sending out any
      email failed. How would you adjust the code?
*/
 
 
 
/*
    Some client side code
*/
var syncList = function (params) {
    params = utils.validateParameters(params, {
        listId: {type: 'number'},
        publishFilter: {type: ['function', 'undefined']}
    });
    var listId = params.listId;
    var synchronization = toJS(inMemoryDb.getData().getIn(['listSynchronizations', listId + '']));
    if (_.isNil(synchronization)) {
        return $q.resolve();
    }
    syncStatusHandler.onListSyncStarted(listId);
    return RestangularWithoutLoadingBar
        .one('lists', listId)
        .all('updated-at')
        .customGET()
        .then(function (timestamps) {
            // Note: 
            // timestamps[key] === undefined means that the server did not send a value
            // timestamps[key] === null means that there are no resources of this type yet ==> no need to sync
            return $q.resolve()
                .then(function () {
                    var shouldSyncEntries = timestamps.listEntries === undefined ||
                        _.isNil(synchronization.nextWatermark) ||
                        moment(timestamps.listEntries).isAfter(moment(synchronization.nextWatermark.updated_at));
                    if (shouldSyncEntries === false || timestamps.listEntries === null) {
                        return;
                    }
                    return synchronizeEntries(listId, synchronization, params.publishFilter);
                })
                .then(function () {
                    var shouldSyncElements = timestamps.listElements === undefined ||
                        _.isNil(_.get(synchronization, ['nextElementWatermark', 'updated_at'])) ||
                        moment(timestamps.listElements).isAfter(moment(synchronization.nextElementWatermark.updated_at));
                    if (shouldSyncElements === false || timestamps.listElements === null) {
                        return;
                    }
                    return synchronizeElements(listId);
                })
                .then(function () {
                    // TODO: Add created_at, updated_at columns for category sort orders 
                    return synchronizeCategorySortOrders(listId);
                })
                .then(function () {
                    var shouldSyncViews = timestamps.views === undefined ||
                        _.isNil(_.get(synchronization, ['nextViewWatermark', 'updated_at'])) ||
                        moment(timestamps.views).isAfter(moment(synchronization.nextViewWatermark.updated_at));
                    if (shouldSyncViews === false || timestamps.views === null) {
                        return;
                    }
                    return synchronizeViews(listId);
                })
                .then(function () {
                    var shouldSyncComments = timestamps.comments === undefined ||
                        _.isNil(_.get(synchronization, ['nextCommentWatermark', 'updated_at'])) ||
                        moment(timestamps.comments).isAfter(moment(synchronization.nextCommentWatermark.updated_at));
                    if (shouldSyncComments === false || timestamps.comments === null) {
                        return;
                    }
                    return synchronizeComments(listId);
                })
                .then(function () {
                    return markListSynchronizationAsDone(listId);
                });
        })
        .catch(function (err) {
            var errorCodesOnWhichToRemoveSynchronization = [
                ZenkitErrorCodes.NOT_FOUND.code,
                ZenkitErrorCodes.LIST_IS_DEPRECATED.code
            ];
            if (_.includes(errorCodesOnWhichToRemoveSynchronization, _.get(err, ['data', 'error', 'code']))) {
                return $q.all([
                    inMemoryDb.update(resources.LIST, {id: listId}, null),
                    inMemoryDb.update(resources.LIST_ELEMENTS, {listId: listId}, null),
                    // This will delete the other resources associated with this list:
                    SynchronizationService.deleteListSynchronization({listId: listId})
                ]);
            }
            return $q.reject(err);
        })
        .catch(function (err) {
            syncStatusHandler.onListSyncFailed(listId);
            return $q.reject(err);
        })
        .then(function () {
            syncStatusHandler.onListSyncDone(listId);
            return;
        });
};
/*
Questions:
* Do you think synchronizing the different resources could be done in parallel?
If so, would there be a downside to doing so?
* Why use _.get(err, ['data', 'error', 'code']) if you could simply do err.data.error.code?
And can you think of a better name for err here?
Challenge:
Imagine we added the created_at and updated_at columns for "categorySortOrders" as the TODO suggests.
Please adjust the code in a way that prevents synchronizing this resource if there was no change.
*/